Files
SDR-Rover/docs/lab047_current_state.md
2026-09-03 13:13:23 +03:00

245 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Lab047: аппаратная передача и восстановление одного JPEG
## Состояние
Программная подготовка и единственный разрешённый аппаратный сеанс завершены.
Первоначальный независимый приём остался незавершённым из-за вычислительного
ограничения `MAX_CANDIDATES_REACHED`, до PHY/FEC/CRC он не дошёл. Это
историческое состояние сохранено и не переименовано в успешный приём.
После исправления только порядка обработки кандидатов выполнен ровно один
полный автономный повторный анализ исходной RX-записи без нового RF. Он собрал
JPEG полностью; последующая диагностическая сверка подтвердила точное
совпадение с переданным файлом. На этапе повторной обработки `RF TX = 0`,
HackRF не запускался.
## Аудит транспорта
Существующий транспорт Lab046 принимает произвольный непустой двоичный объект.
Размер 16384 байта был параметром Lab046C, а не ограничением протокола.
Число фрагментов вычисляется из фактического размера объекта, длина последнего
фрагмента восстанавливается из его собственных метаданных.
JPEG поэтому передаётся как обычная последовательность байтов. Изменения в
`protocol/`, Lab045, FEC и физическом уровне не потребовались и не выполнялись.
## Демонстрационный JPEG
Выбрана существующая настоящая фотография
`data/raw/lab011_scene.jpg`: поле, грунтовая дорога и деревья. Исходный файл не
изменялся. Подготовка полностью фиксирована:
- цветовой режим RGB;
- размер 320 x 240 пикселей;
- фильтр уменьшения LANCZOS;
- JPEG quality 35;
- цветовая субдискретизация 4:2:0;
- `optimize = false`;
- `progressive = false`.
Полученный файл `data/processed/lab047/tx_image.jpg` имеет 8724 байта,
формат JPEG, режим RGB, размер 320 x 240 и SHA-256
`e913dab9ac32795250880a4be67fbbbf89a4f96536842476ab591d1acaafc02a`.
Pillow полностью читает файл и не обнаруживает усечения.
## Программный сквозной проход
Выполнена цепочка:
`tx_image.jpg -> bytes -> Lab046 fragmentation -> Lab045 FEC/BPSK ->`
`идеальный канал -> PHY/FEC/CRC -> ObjectAssembler -> recovered_image.jpg`.
Фактический результат:
- фрагментов: 36;
- защищённых BPSK-кадров: 36;
- CRC PASS / FAIL: 36 / 0;
- действительных фрагментов: 36;
- пропущенных фрагментов: 0;
- `OBJECT COMPLETE = YES`;
- SHA-256 восстановленного файла:
`e913dab9ac32795250880a4be67fbbbf89a4f96536842476ab591d1acaafc02a`;
- `SHA MATCH = YES`;
- ошибочных байтов: 0;
- ошибочных битов: 0;
- Pillow распознаёт восстановленный файл как JPEG 320 x 240 RGB;
- `IMAGE DECODE = PASS`.
## Учёт будущего радиопотока
Каждый полный кадр Lab045 содержит 2 306 400 комплексных отсчётов. Для
фактических 8724 байт JPEG рассчитано:
- число отсчётов TX: 83 030 400;
- размер будущего `tx_stream.cs8`: 166 060 800 байт;
- расчётная длительность TX: 10,3788 с;
- полезная скорость по данным JPEG: 6724,48 бит/с;
- плановая длительность RX: 15,0 с;
- объём RX: 120 000 000 комплексных отсчётов, 240 000 000 байт;
- упреждение запуска RX: 0,75 с.
Большие `tx_stream.cs8`, `rx_stream.cs8` и сырые IQ в Git не создавались и не
добавлялись.
## Подготовленный аппаратный запуск
`experiments/lab047_jpeg_object_transport.py` содержит отдельные режимы для
формирования будущего TX-потока без RF, одного аппаратного захвата и одного
независимого полного анализа. Аппаратный режим требует одновременно три явных
ключа командной строки и обязательный новый признак разрешения внутри функции.
До попытки создаётся одноразовый файл-свидетель; автоматического повтора нет.
Параметры будущего опыта зафиксированы:
- MASTER/TX: `000000000000000097c063dc323b97d3`;
- SLAVE/RX: `000000000000000097c063dc2e5327d3`;
- центральная частота: 1 400 000 000 Гц;
- частота дискретизации: 8 МГц;
- BPSK: 20 ксимв/с, 400 отсчётов на символ;
- цифровое смещение несущей: +50 кГц;
- TX VGA: 10 дБ;
- RX LNA/VGA: 24/24 дБ;
- RF amplifier и Bias-Tee: выключены на обоих устройствах;
- общий генератор: TCXO 10 МГц -> MASTER -> CLKOUT -> SLAVE CLKIN;
- ожидаемый регистр 29 обоих устройств после проверки: `0x26`.
## Независимое обнаружение
Для каждой новой записи первый порог вычисляется заново только по фону до TX:
`threshold = Q99.9 локальных максимумов + 4 x MAD локальных максимумов`.
Интервал калибровки равен 0,0-0,5 с записи, затем порог фиксируется до полного
декодирования. Независимый контрольный фон расположен в интервале 12,0-15,0 с.
Строгий каскад остаётся прежним:
`точная синхронизация -> CFO -> фаза -> PHY header -> FEC -> CRC`.
Кадр принимается только при `CRC PASS`. Исторический
`IQ_PREAMBLE_THRESHOLD = 0.65` не изменён. Интерфейс независимого приёмника
получает только путь к RX-записи и выходной каталог. Он не получает смещения
TX, ожидаемое число кадров, индексы фрагментов передатчика, исходный JPEG,
пакеты или кодированные биты. Сравнение с TX-файлом вынесено в отдельную
функцию, которая открывается только после сохранённого полного независимого
вердикта.
## Единственный аппаратный сеанс
3 сентября 2026 года выполнен один непрерывный RF TX без повторов. Частота
равна 1400 МГц, фактическая длительность TX — 10,38030 с. RX продолжался
15,00875 с и сохранил 120000000 комплексных отсчётов, или 240000000 байт.
RX overruns 0, TX underruns 0. Проверка общего опорного генератора прошла.
Повторная передача не выполнялась: `RF TX COUNT = 1` за аппаратный сеанс и
`RF TX = 0` на этапе автономной обработки.
По фону до передачи до декодирования зафиксированы:
- Q99.9 локальных максимумов: `0.020810436457395554`;
- MAD локальных максимумов: `0.002538509201258421`;
- порог `Q99.9 + 4 * MAD`: `0.030964473262429237`.
На независимом контрольном фоне после передачи maximum равен
`0.026494961231946945`, кандидатов 0. Порог после аппаратного результата и
при повторной обработке не менялся.
Первоначальный приём остановился после 71113 локальных максимумов и заполнения
промежуточного списка из 10000 кандидатов. Сработало
`MAX_CANDIDATES_REACHED`; строгая ступень не запускалась. Поэтому сохранённый
исторический результат сформулирован точно:
`ORIGINAL HARDWARE RECEIVE = INCOMPLETE DUE TO MAX_CANDIDATES_REACHED`, а не
PHY FAIL, FEC FAIL, CRC FAIL или отказ передачи JPEG.
## Потоковая обработка кандидатов
В `lab046c_offline_recovery.py` устранено предварительное накопление всех
кандидатов. Блоки IQ и локальные максимумы идут по возрастанию смещения, а
каждый кандидат сразу передаётся строгой ступени. Защитный предел сохранён и
теперь ограничивает число фактически выполненных строгих проверок; его
значение 100000 не зависит от числа кадров JPEG.
После принятого по CRC кадра позиция перескакивает за принадлежащую ему область.
После плохого кандидата она продвигается на один отсчёт, поэтому близкий
настоящий кадр не скрывается. Точный повтор одного смещения подавляется;
произвольного радиуса подавления и глобального отношения первого пика ко
второму нет. Перекрытия блоков имеют однозначное владение и не породили
дубликатов.
Для списка кандидатов измерено около 108 байт на запись; при потоковой
обработке пиковый объём такого списка составил 49588 байт. Основной временный
объём определяет обработка блока IQ: приблизительно 1545755352 байта
(около 1,44 ГиБ).
## Автономный результат исходной RX-записи
После программного шлюза выполнен ровно один полный независимый проход всей
15-секундной записи. Передаточные смещения, период кадров, ожидаемое число
кадров, номера фрагментов, исходный 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 с. Первоначально поле `completed`
осталось ложным из-за отдельной ошибки учёта границы: последнее допустимое
начало корреляции было принято за конец обработанной области IQ. Исходный JSON
результата не изменён, полный поиск не повторяли. В отдельном исправленном JSON
после проверки исчерпания всех восьми блоков граница изменена с 119471220 на
120000000 и `completed` на `true`; порог не менялся,
`full_decoder_rerun = false`.
Только после сохранения завершённого независимого вердикта открыты опорные
данные передатчика. Совпали 36 из 36 кадров, пропущено 0, ложных CRC PASS 0.
До FEC обнаружено 19 ошибок кодированных бит, после FEC — 0 ошибок
протокольных бит. В независимый результат кадры не добавлялись.
Восстановленный `recovered_image.jpg` имеет 8724 байта. Его SHA-256 и SHA-256
переданного файла одинаковы:
`e913dab9ac32795250880a4be67fbbbf89a4f96536842476ab591d1acaafc02a`.
Ошибочных байтов 0, ошибочных битов 0. Pillow полностью декодирует JPEG как
изображение RGB 320 x 240. Итог:
`LAB047 OFFLINE RECOVERY OF HARDWARE CAPTURE = PASS`; единственный RF-сеанс
фактически передал JPEG успешно, а первоначальную обработку остановил
вычислительный предел.
## Артефакты
- `data/processed/lab047/tx_image.jpg`;
- `data/processed/lab047/recovered_image.jpg`;
- `data/processed/lab047/result.json`;
- `data/processed/lab047/result.txt`.
Большая RX-запись и результаты аппаратного сеанса оставлены вне Git в
`C:\Users\user\Documents\SDR_Rover_Lab047_raw\20260903_115747`. Исходный
`independent_reprocess_result.json` сохранён неизменным; исправление только
признака полного покрытия находится в
`independent_reprocess_result_corrected.json`, а разрешённая послерезультатная
сверка — в `post_verdict_diagnostics.json`.
## Проверки
- `python tools/quick_gate.py`: PASS, 540 проверок pytest и 10 быстрых
функциональных проверок лабораторных;
- `python -m pytest tests/ -q`: 540 passed, 0 failed;
- `git diff --check`: PASS.
Предупреждение pytest о невозможности создать служебный `.pytest_cache` не
относится к тестам и не изменило код возврата.
## Следующий этап
STOP. Разрешение на единственный аппаратный процесс Lab047 израсходовано.
Новый RF, повтор передачи, изменение порога, PHY, FEC, CRC или Lab045 без
отдельной новой постановки не выполнять. `RF TX = 0`; HackRF не запускать.