# 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 и выполнить один ограниченный аппаратный прогон.