Lab047: transmit JPEG over real RF link

This commit is contained in:
LittleSam129
2026-09-03 13:13:23 +03:00
parent b0111d2232
commit 6fb7e4ec54
11 changed files with 2858 additions and 17 deletions

View File

@@ -1097,3 +1097,176 @@ passed и 0 failed, `git diff --check` прошёл.
STOP. Новый RF, JPEG, видео, QPSK, 180 МГц и FEC 12+3 без отдельной постановки
не начинать.
# Запись 033
## Дата
2 сентября 2026 года
## Тема
Lab047: программная подготовка первой передачи настоящего JPEG через
существующий транспорт Lab046.
## Выполнено
Проведён аудит `protocol/image_fragments.py` и Lab046-Lab046C. Подтверждено,
что транспорт принимает произвольный непустой двоичный объект, а размер 16384
байта был только параметром прежнего опыта. JPEG можно передавать без изменения
протокола, Lab045, FEC и физического уровня; эти части не изменялись.
Для демонстрации выбрана существующая настоящая фотография
`data/raw/lab011_scene.jpg`. Исходный файл сохранён без изменений. По одной
фиксированной процедуре подготовлен JPEG RGB 320 x 240: LANCZOS, quality 35,
4:2:0, без optimize и progressive. Получено 8724 байта и SHA-256
`e913dab9ac32795250880a4be67fbbbf89a4f96536842476ab591d1acaafc02a`.
Файл распознаётся Pillow как полный JPEG.
Выполнен программный сквозной проход через фрагментацию Lab046, 36 защищённых
кадров Lab045, идеальный BPSK-канал, PHY/FEC/CRC и независимую сборку объекта.
Получено 36 CRC PASS, 0 CRC FAIL, принято 36 фрагментов, пропущено 0,
`OBJECT COMPLETE = YES`. Восстановленный `recovered_image.jpg` имеет 8724
байта, совпадающую SHA-256, 0 ошибочных байтов и 0 ошибочных битов. Pillow
декодирует восстановленный JPEG как RGB 320 x 240.
По фактическому размеру рассчитан будущий поток: 36 кадров, 83 030 400
комплексных отсчётов, 166 060 800 байт `cs8`, 10,3788 с и 6724,48 бит/с
полезных данных. RX запланирован на 15,0 с: 120 000 000 отсчётов и 240 000 000
байт, начало на 0,75 с раньше TX.
Подготовлен отдельный аппаратный исполнитель с фиксированными параметрами
успешной точки Lab046C: 1400 МГц, 8 МГц, BPSK 20 ксимв/с, 400 отсчётов на
символ, +50 кГц, TX VGA 10 дБ, RX LNA/VGA 24/24 дБ, усилители и Bias-Tee
выключены, MASTER и SLAVE закреплены по серийным номерам. Аппаратный режим
закрыт тремя явными ключами и отдельным параметром разрешения функции,
запрещает автоматический повтор и использует проверку общей опоры с reg29
`0x26`.
Для будущей новой RX-записи подготовлена динамическая калибровка первого
каскада только по фону до передачи: Q99.9 локальных максимумов плюс 4 MAD.
Порог фиксируется до полного декодирования; фон после передачи остаётся
независимой контрольной выборкой. Строгий каскад PHY/FEC/CRC и исторический
порог 0.65 не изменены. Интерфейс независимого приёмника не принимает TX
offsets, ожидаемое число кадров, индексы TX-фрагментов, исходный JPEG, пакеты
или кодированные биты. TX reference разрешён отдельной диагностической функции
только после сохранённого полного независимого вердикта.
Созданы малые демонстрационные артефакты в `data/processed/lab047`: переданный
и восстановленный JPEG, JSON и краткий текстовый результат. Большие потоки
`cs8`, сырые IQ и аппаратные данные не создавались. HackRF не запускался,
`RF TX = 0`. `python tools/quick_gate.py` прошёл с 524 проверками pytest и 10
быстрыми функциональными проверками лабораторных; полный запуск
`python -m pytest tests/ -q` дал 524 passed и 0 failed; `git diff --check`
прошёл. Git add, commit и push не выполнялись.
## Следующий этап
STOP. До любой аппаратной операции запросить отдельное новое разрешение на
один непрерывный процесс передачи одного JPEG при 1400 МГц. Старое разрешение
Lab046C не использовать. Автоматические повторы запрещены.
# Запись 034
## Дата
3 сентября 2026 года
## Тема
Lab047: единственная аппаратная передача JPEG и автономное восстановление
исходной RX-записи после устранения ограничения `MAX_CANDIDATES`.
## Выполнено
После отдельного точного разрешения выполнен один непрерывный RF TX без
повторов при 1400 МГц. Переданы 36 защищённых кадров с JPEG размером 8724
байта. Фактическая длительность TX составила 10,38030 с. RX продолжался
15,00875 с и сохранил 120000000 комплексных отсчётов, или 240000000 байт;
RX overruns 0, TX underruns 0. Общий опорный генератор прошёл проверку.
`RF TX COUNT = 1`; повтор передачи не выполнялся.
До декодирования по фону до передачи зафиксирован порог первого каскада
`Q99.9 + 4 * MAD`: Q99.9 `0.020810436457395554`, MAD
`0.002538509201258421`, threshold `0.030964473262429237`. На независимом
контрольном фоне maximum равен `0.026494961231946945`, кандидатов 0. Порог
после аппаратного результата и при автономной обработке не менялся.
Первоначальный независимый приём остановился после 71113 локальных максимумов
и накопления списка из 10000 кандидатов. Сработало
`MAX_CANDIDATES_REACHED`; строгий каскад PHY/FEC/CRC вообще не запускался.
Исторический результат сохранён без переименования:
**ORIGINAL HARDWARE RECEIVE = INCOMPLETE DUE TO MAX_CANDIDATES_REACHED**. Это
не PHY FAIL, FEC FAIL, CRC FAIL и не доказательство отказа передачи JPEG.
Аудит `lab046c_offline_recovery.py` показал, что прежняя двухступенчатая схема
сначала накапливала кандидатов всего файла и при достижении предела передавала
строгому каскаду пустой список. Один кандидат занимает приблизительно 108
байт; основную память использовал 16-миллионный блок IQ. Проверка смещений
выявила ожидаемые боковые максимумы периодической PRBS7-преамбулы, но не
дубликаты на границах блоков.
Реализована последовательная схема: кандидаты каждого блока идут по
возрастанию смещения и немедленно проходят строгую проверку. Защитный предел
100000 теперь ограничивает число выполненных строгих проверок и не зависит от
числа кадров JPEG. После CRC PASS позиция перескакивает за область принятого
кадра; после плохого кандидата продвигается на один отсчёт. Подавляется только
точный повтор смещения или кандидат, принадлежащий уже принятому кадру.
Произвольный радиус подавления и глобальное отношение первого пика ко второму
не применяются. Добавлены проверки для потока более 10000 кандидатов,
немедленной обработки, прохождения настоящего кадра среди шума, владения
принятым кадром, перекрытий блоков, близкого кандидата после плохого,
защитного предела, неизменности порога и отсутствия ожидаемого числа кадров в
интерфейсе.
После программного шлюза выполнен ровно один полный автономный проход всей
исходной 15-секундной RX-записи. Смещения и период кадров передатчика,
ожидаемое число кадров, номера TX-фрагментов, исходный JPEG, пакеты и
кодированные биты не использовались. Получено 185828 локальных максимумов,
32414 кандидатов первого каскада и 69 строгих проверок; 32345 кандидатов
пропущены как принадлежащие уже принятому локальному событию, точных повторов
на перекрытиях 0. PHY-заголовок PASS/FAIL `36/33`, FEC
attempts/PASS/FAIL `36/36/0`, CRC PASS/FAIL `36/0`, действительных кадров и
фрагментов `36/36`, отсутствующих фрагментов 0. До открытия опорных данных
передатчика получено **OBJECT COMPLETE = YES**.
Все восемь блоков оценки были исчерпаны, защитные пределы не сработали. Полное
время обработки составило 37,42391 с, строгая ступень — 32,459969 с, в среднем
0,470434 с на строгую проверку. Приблизительный максимальный временный объём
памяти равен 1545755352 байтам, около 1,44 ГиБ; пиковая память списка
кандидатов — 49588 байт.
После единственного полного прохода обнаружена только ошибка учёта признака
завершённости: последнее допустимое начало корреляции было принято за конец
обработанной области IQ, поэтому при исчерпанных восьми блоках поле
`completed` ошибочно осталось ложным. Полный поиск не повторялся, исходный JSON
с SHA-256 `2a16741aa7fd20cfec179a7340300d0884095ab9f781b877230136ea8d249caf`
сохранён неизменным. В отдельном исправленном JSON после проверки числа блоков
граница покрытия изменена с 119471220 на 120000000 и `completed` на `true`;
`full_decoder_rerun = false`, `threshold_changed = false`.
Только после сохранения завершённого независимого вердикта открыты опорные
данные передатчика и диагностически повторно расшифрованы 36 уже принятых окон,
без второго поиска по capture. Совпали 36/36 кадров, пропущено 0, ложных CRC
PASS 0, дубликатов 0. До FEC обнаружено 19 ошибок кодированных бит, после FEC
0 ошибок протокольных бит. В независимый результат кадры не добавлялись.
Восстановленный JPEG имеет 8724 байта, 0 ошибочных байтов и 0 ошибочных бит.
SHA-256 восстановленного и переданного файлов совпадает:
`e913dab9ac32795250880a4be67fbbbf89a4f96536842476ab591d1acaafc02a`.
Pillow полностью декодирует JPEG как RGB 320 x 240. Итог:
**LAB047 OFFLINE RECOVERY OF HARDWARE CAPTURE = PASS**. Единственный RF-сеанс
фактически передал JPEG успешно; первоначальный приём не завершился только
из-за вычислительного ограничения `MAX_CANDIDATES`.
На этапе исправления и автономной обработки HackRF не запускался, `RF TX = 0`.
`python tools/quick_gate.py` прошёл с 540 проверками pytest и 10 быстрыми
функциональными проверками лабораторных; `python -m pytest tests/ -q` дал 540
passed и 0 failed; `git diff --check` прошёл. Git add, commit, push, pull и
fetch не выполнялись.
## Следующий этап
STOP. Разрешение на единственный аппаратный процесс Lab047 израсходовано.
Новый RF, повтор передачи, изменение порога, PHY, FEC, CRC или Lab045 без
отдельной новой постановки не выполнять. `RF TX = 0`; HackRF не запускать.