218 lines
14 KiB
Markdown
218 lines
14 KiB
Markdown
# Lab045: текущее состояние
|
||
|
||
## Статус
|
||
|
||
**РЕАЛИЗАЦИЯ ГОТОВА. ПРОГРАММНО ПРОВЕРЕНО. АППАРАТНАЯ ПРОВЕРКА ПРОЙДЕНА
|
||
(RESULT A). РЕАЛЬНАЯ FEC-КОРРЕКЦИЯ В ЭФИРЕ ДОКАЗАНА.**
|
||
|
||
Работа выполнена от фактического HEAD
|
||
`72f933a32b0dfaef3a4af5bd2cb4a2c` (`Lab044: validate arbitrary BPSK
|
||
packet reception`). 1 сентября 2026 года выполнен **ровно один** аппаратный
|
||
RF-прогон Lab045: RF TX count = 1, без повторов.
|
||
|
||
## Аппаратный результат (1 сентября 2026 года) — RESULT A
|
||
|
||
Каталог артефактов:
|
||
`C:\Users\user\Documents\SDR_Rover_Lab045_raw\20260901_103434_bpsk_fec\`
|
||
|
||
- **RF TX count = 1** (ровно одна передача, `TransmitGuard`, без повторов).
|
||
- **Инвентарь плат** подтверждён по серийникам: MASTER/TX `…323b97d3`,
|
||
SLAVE/RX `…2e5327d3`.
|
||
- **Общий опорный генератор PASS**: MASTER reg29 = 0x26 (38), SLAVE reg29 =
|
||
0x26 (38), SLAVE CLKIN = DETECTED (за 2 опроса, 141,8 мс).
|
||
- **Независимая синхронизация по преамбуле PASS**: peak/median +34,3 дБ,
|
||
peak/second +12,7 дБ, payload не использовался.
|
||
- **Защищённый PHY header PASS** (packet length = 268 восстановлена
|
||
мажоритарно, checksum сошёлся).
|
||
- **Канал был реально шумным**: SNR всего **2,63 дБ**, ошибок преамбулы
|
||
**39/1280** (BER 3,05 %), сырых ошибок кодированного потока
|
||
**155/4300** (BER **3,60 %**).
|
||
- **Свёрточный декодер Витерби исправил все ошибки**: post-FEC ошибок
|
||
пакета — **0/2144**, ошибок payload — **0/2048**, байтовых ошибок — 0.
|
||
- **CRC = PASS**, protocol header PASS (SYNC 0xAA55, версия 1, тип 2
|
||
(телеметрия), sequence 44, payload_length 256).
|
||
- **Payload восстановлен побитово точно**: SHA-256 `rx_payload.bin`
|
||
совпал с `tx_payload.bin` (`cb9d06fe…`); `rx_packet.bin` совпал с
|
||
`tx_packet.bin` (`ed5a5713…`).
|
||
|
||
### Главный научный итог
|
||
|
||
**REAL RF FEC CORRECTION DEMONSTRATED = YES.** До декодера в реальном
|
||
принятом сигнале присутствовали 155 ошибок кодированных бит (3,60 %),
|
||
после мягкого декодера Витерби осталось 0 ошибок, CRC пройден, произвольный
|
||
256-байтный payload восстановлен без единой ошибки. Это прямое
|
||
доказательство работы помехоустойчивого кода на реальном радиоканале — при
|
||
таком SNR незащищённый пакет Lab044 не имел бы шансов пройти CRC.
|
||
|
||
### Радиометрика прогона
|
||
|
||
CFO 0,128 Гц (общий опорник), phase −133,9°, separation 2,707,
|
||
timing offset −2 отсчёта. ADC: peak_complex 5,83 code, peak_component 5,0,
|
||
p99.9 ≈ 4,12 code (headroom 122). Clipping 0, near-int8 0. RX overruns 0,
|
||
TX underruns 0. BEFORE/DURING/AFTER: RMS после DC 0,832 / 0,874 / 0,846 —
|
||
на интервале кадра (0,288 с) сигнал слегка выше фона, хвост p99.9 during
|
||
4,21 против 4,12, перегрузки АЦП нет.
|
||
|
||
### Cleanup
|
||
|
||
MASTER CLKOUT OFF (SLAVE CLKIN «no clock signal detected»), SLAVE CLKOUT
|
||
OFF, зависших `hackrf_transfer.exe` нет. SHA-256 всех реально созданных
|
||
бинарных артефактов вычислены дважды и совпали.
|
||
|
||
Пост-RF программный шлюз повторно пройден: quick_gate PASS,
|
||
`pytest` 417 passed, `git diff --check` чист. Второй TX не выполнялся.
|
||
|
||
## Назначение
|
||
|
||
Lab045 добавляет исправление неизвестных битовых ошибок внутри принятого
|
||
радиопакета. Существующий `protocol/packet_erasure_fec.py` не менялся: его
|
||
GF(256) 12+3 предназначен для восстановления известных потерянных shards на
|
||
более высоком уровне, а не для исправления неизвестных позиций ошибочных битов.
|
||
|
||
Программно доказан тракт:
|
||
|
||
`256 произвольных байт -> существующий protocol packet и CRC32 -> MSB-first
|
||
bits -> convolutional R=1/2, K=7 -> interleaver -> noisy soft BPSK ->
|
||
deinterleaver -> soft Viterbi -> существующий parser/CRC -> исходный payload`.
|
||
|
||
## Свёрточный код
|
||
|
||
- `K = 7`, память `m = 6`, 64 состояния.
|
||
- Скорость `R = 1/2`.
|
||
- Порождающие многочлены в порядке выходных битов: `G0 = 171 octal`,
|
||
`G1 = 133 octal`.
|
||
- Полный регистр: `(input_bit << 6) | state`; в `state` находятся шесть
|
||
предыдущих входных битов, самый свежий занимает бит 5.
|
||
- Начальное состояние 0.
|
||
- К информационным битам добавляются шесть нулевых tail bits.
|
||
- Финальное состояние решётки 0; traceback начинается только из состояния 0;
|
||
tail bits удаляются из результата.
|
||
- BPSK-соглашение совпадает с `protocol.bpsk_radio`: `0 -> -1`, `1 -> +1`.
|
||
- Soft Viterbi получает вещественные значения до hard slicing. Branch metric:
|
||
сумма квадратов евклидовых расстояний до ожидаемой пары `{-1,+1}`.
|
||
|
||
Encoder проверен не только round trip с decoder: есть фиксированные короткие
|
||
эталонные векторы и второй независимо записанный reference encoder.
|
||
|
||
## Перемежитель
|
||
|
||
Детерминированный блочный interleaver записывает индексы строками и читает по
|
||
столбцам. Для Lab045 используется 64 столбца. Неполная последняя строка не
|
||
дополняется: отсутствующие ячейки пропускаются, поэтому длина не меняется.
|
||
Одна и та же permutation применяется к TX bits и обратно к RX soft values.
|
||
Перед применением проверяется, что каждый индекс встречается ровно один раз.
|
||
|
||
## Защищённый PHY header
|
||
|
||
Незащищённый header имеет 6 байт, 48 бит:
|
||
|
||
- magic `0xD391`, 16 бит;
|
||
- версия режима Lab045 `1`, 8 бит;
|
||
- длина существующего protocol packet в байтах, 16 бит;
|
||
- младшие 8 бит CRC32 предыдущих пяти байт, 8 бит.
|
||
|
||
Каждый отдельный header bit передаётся буквально как `b,b,b`; формат не
|
||
является конкатенацией `header|header|header`. После soft majority выполняется
|
||
fail-closed проверка magic, версии, checksum и диапазона длины `12..1024`
|
||
(12 байт равны минимальным header + CRC существующего protocol packet).
|
||
По принятой длине вычисляется точное число coded symbols. Если их физически не
|
||
хватает, Viterbi и protocol parser не запускаются. Лишние trailing soft values
|
||
детерминированно игнорируются.
|
||
|
||
## Независимый порядок приёма
|
||
|
||
Аппаратный адаптер подготовлен, но не запускался. Он принимает только IQ и
|
||
переиспользует из Lab044 независимый PRBS7 detector, timing, CFO и
|
||
phase/polarity recovery. На выходе берётся `normalized.real` до строки hard
|
||
slicing Lab044. Далее порядок фиксирован:
|
||
|
||
`PHY sync -> protected PHY header -> deinterleave soft -> soft Viterbi ->
|
||
reconstructed protocol packet -> existing parse_packet -> existing CRC`.
|
||
|
||
RX analyzer не принимает TX packet или payload. Сравнение pre-FEC, post-FEC и
|
||
payload с TX вынесено в отдельную диагностическую функцию, вызываемую только
|
||
после независимого CRC verdict.
|
||
|
||
## Точный размер кадра
|
||
|
||
| Величина | Значение |
|
||
|---|---:|
|
||
| Protocol packet | 268 bytes |
|
||
| Information bits | 2144 |
|
||
| Tail bits | 6 |
|
||
| Входных битов encoder с tail | 2150 |
|
||
| Coded bits | 4300 |
|
||
| Interleaver elements | 4300 |
|
||
| Незащищённый PHY header | 48 bits |
|
||
| Защищённый PHY header | 144 bits |
|
||
| PRBS7 preamble | 1280 bits |
|
||
| Всего BPSK-символов кадра | 5724 |
|
||
| Samples per symbol | 400 |
|
||
|
||
Учёт кадра и формы сигнала — это две разные величины, и их нужно различать:
|
||
|
||
| Величина | Символы | Отсчёты | Длительность при 8 MS/s |
|
||
|---|---|---|---|
|
||
| **Только информационные BPSK-символы кадра** | 5724 | 2 289 600 | 286,2 мс |
|
||
| **Фактически сгенерированная форма сигнала** | 5766 | 2 306 400 | 288,3 мс |
|
||
| Разница | 42 | 16 800 | 2,1 мс |
|
||
|
||
Откуда берётся разница в 42 символа (16 800 отсчётов) — подтверждено прямо по
|
||
формирователю `shape_frame_like_lab042` (свёртка `guard + upsampled + guard`
|
||
с ФРК-фильтром в режиме `full`, длина = `(N + 2·guard + span)·sps`):
|
||
|
||
- **32 символа** — защитные интервалы Lab042 (`LAB042_GUARD_SYMBOL_COUNT = 16`
|
||
с каждой стороны, до и после кадра);
|
||
- **10 символов** — длина корневого приподнятого косинуса (ФРК)
|
||
`LAB042_RRC_SPAN_SYMBOLS = 10` (переходный хвост фильтра от режима `full`).
|
||
|
||
Это не guard/RRC «на веру» и не дефект сигнала: это ровно тот же механизм
|
||
формирования, что и в проверенном Lab044, где 3456 символов кадра дают
|
||
1 399 200 отсчётов = (3456 + 42)·400. Форму сигнала менять не нужно.
|
||
|
||
Для сравнения Lab044: кадр 3456 символов, форма 1 399 200 отсчётов, 174,9 мс.
|
||
Lab045 добавляет к кадру 2268 символов. Старая оценка около 280 мс для Lab044
|
||
не используется.
|
||
|
||
## Фактические программные результаты
|
||
|
||
- Новый набор `tests/test_lab045_hackrf_bpsk_fec.py`: 41 passed.
|
||
- Идеальный soft BPSK: CRC PASS, payload совпал побайтово.
|
||
- Детерминированный канал с `bit_error_probability=0.006`, seed 7: до FEC
|
||
28 ошибок из 4300 coded bits (`BER = 0.0065116`), после FEC 0 ошибок в
|
||
protocol packet, CRC PASS, payload точный.
|
||
- Пачка из 14 соседних channel symbols: после interleaver/FEC CRC PASS,
|
||
payload точный.
|
||
- Детерминированный Gaussian noise с `sigma=0.45`, seed 45: CRC PASS.
|
||
- На отдельном честном AWGN-примере из 128 information bits hard slicing дал
|
||
15 channel-bit errors и после hard Viterbi осталось 5 information-bit
|
||
errors; soft Viterbi по тем же значениям дал 0 information-bit errors.
|
||
Это доказывает использование амплитудной информации, но не является
|
||
измерением выигрыша в dB реального канала.
|
||
- Синтетическая cs8 IQ-форма прошла тот же detector/timing/CFO/phase adapter,
|
||
что Lab044: PHY sync PASS, CRC PASS, payload точный.
|
||
- Majority, checksum, bad magic, bad version, impossible length, truncated
|
||
header/body, extra trailing data, CRC corruption и отсутствие TX-data
|
||
leakage покрыты отдельными тестами.
|
||
|
||
## Software gate
|
||
|
||
- `python tools/quick_gate.py`: PASS; 414 тестов ядра, 5 функциональных
|
||
проверок лаб, 13 штатно пропущенных проверок.
|
||
- `python -m pytest tests/ -q`: 414 passed, 0 failed, 0 skipped.
|
||
- `git diff --check`: PASS.
|
||
- Pytest сообщил только предупреждение о невозможности создать `.pytest_cache`
|
||
из-за прав каталога; на выполнение и итог тестов это не повлияло.
|
||
|
||
## Ограничения и следующий шаг
|
||
|
||
`run_hardware_experiment()` намеренно завершается `NotImplementedError`, а CLI
|
||
с `--hardware` возвращает ненулевой код и печатает `RF TX = 0`. Аппаратный
|
||
Lab045, повтор Lab044, gain tuning, QPSK, JPEG и video в этой сессии не
|
||
выполнялись.
|
||
|
||
Следующий этап возможен только по отдельному разрешению: дополнить аппаратную
|
||
обвязку Lab045 доказанными common-clock preflight, one-TX guard, artifact и
|
||
cleanup механизмами Lab044, повторно пройти software gate и выполнить один
|
||
ограниченный аппаратный прогон.
|