Files
SDR-Rover/docs/lab045_current_state.md
LittleSam129 62a376c811 Lab045: demonstrate real RF BPSK error correction
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-01 10:49:00 +03:00

14 KiB
Raw Permalink Blame History

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