Files
SDR-Rover/PROJECT_LOG.md
2026-09-03 14:42:02 +03:00

119 KiB
Raw Blame History

Инженерный журнал SDR Rover Link

Назначение журнала

Этот файл содержит хронологию разработки проекта SDR Rover Link.

В журнале фиксируются:

  • выполненные работы;
  • полученные результаты;
  • обнаруженные ошибки;
  • принятые технические решения;
  • результаты экспериментов;
  • планы следующего этапа.

Записи не следует удалять. Если решение изменилось, необходимо добавить новую запись и объяснить причину изменения.


Запись 001

Дата

10 июля 2026 года

Тема

Создание структуры проекта и локального Git-репозитория.

Выполнено

  1. Проверена установленная версия Git:
git version 2.51.1.windows.1

Запись 002

Дата

27 июля 2026 года

Тема

Завершение Lab028: пакетирование синхронного BASE + ROI.

Выполнено

  • Реализован фиксированный бинарный заголовок размером 32 байта.
  • Добавлены packet CRC32 для заголовка и payload и object CRC32 для полного JPEG.
  • Исследованы размеры payload 64, 128, 256, 512 и 1024 байта.
  • Размер payload 512 байт принят как рабочий кандидат.
  • Окончательный выбор размера пакета перенесён в Lab029.

Запись 003

Дата

27 июля 2026 года

Тема

Завершение Lab029: моделирование потерь и ошибок видеопакетов.

Выполнено

  • Исследованы независимые потери пакетов и независимые битовые ошибки.
  • Проверены короткие, средние и длинные серии потерь по модели Gilbert–Elliott.
  • Выполнено сравнение payload 256, 512 и 1024 байта.
  • Подтверждены packet CRC32, изоляция соседних кадров и атомарная сборка BASE + ROI.
  • Зафиксировано ограничение пакетной временной шкалы Lab029.
  • Сравнение помех одинаковой физической длительности перенесено в Lab029B.

Запись 004

Дата

27 июля 2026 года

Тема

Завершение Lab029B: временная модель серийных потерь.

Выполнено

  • Помехи смоделированы на непрерывной временной шкале.
  • Контрольная скорость передачи установлена равной 300 кбит/с.
  • Исследованы средние длительности Bad 10, 50, 200 и 1000 мс.
  • Payload 512 байт выбран для дальнейшей разработки.
  • Payload 1024 байта оставлен резервным вариантом.
  • Подтверждено, что без исправления ошибок возможны длительные прерывания видеопотока.

Запись 005

Дата

29 июля 2026 года

Тема

Завершение Lab030: блочное исправление стираний.

Выполнено

  • Реализовано блочное исправление стираний над GF(256).
  • Проверены режимы без исправления, 8+1, 8+2 и 8+4.
  • Режим 8+2 выбран основным рабочим режимом.
  • Режим 8+4 оставлен контрольным.
  • Подтверждено, что без перемежения продолжительные серии потерь не исправляются.
  • Следующая лабораторная посвящена перемежению пакетов.

Запись 006

Дата

29 июля 2026 года

Тема

Завершение Lab031: перемежение блоков исправления ошибок.

Выполнено

  • Исследовано перемежение блоков исправления ошибок.
  • Проверены глубины D=1, 2, 4 и 8.
  • Подтверждено, что глубокое перемежение повышает задержку сильнее, чем полезность для операторского видеопотока.
  • D=1 оставлен основным режимом.
  • D=2 сохранён как резервный вариант.
  • D=4 и D=8 исключены из основной линии разработки.
  • Следующая лабораторная подбирает размер блока и количество проверочных пакетов.

Запись 007

Дата

29 июля 2026 года

Тема

Завершение Lab032: параметры блочного исправления потерянных пакетов.

Выполнено

  • Исследованы параметры блочного исправления потерянных пакетов.
  • Сравнивались режимы без исправления, 4+1, 8+2, 12+3, 6+2, 8+3, 4+2 и 8+4.
  • Режим 12+3 выбран основным.
  • Его транспортный поток составляет 226,951 кбит/с.
  • Запас до контрольных 300 кбит/с составляет 73,049 кбит/с.
  • Режим 8+4 оставлен усиленным экспериментальным вариантом.
  • Режим 8+3 не принят из-за отсутствия устойчивого преимущества.
  • Подтверждено, что продолжительные помехи нельзя компенсировать только увеличением числа проверочных пакетов.
  • Следующий этап посвящён совместной передаче команд, телеметрии и видео с приоритетным обслуживанием.

Запись 008

Дата

3 августа 2026 года

Тема

Завершение Lab033: общий пакет канала и приоритетное обслуживание.

Выполнено

  • Добавлен общий 32-байтный заголовок канала для команд, телеметрии и видео.
  • Общая предложенная нагрузка составляет 258,214 кбит/с.
  • Подтверждено, что FIFO не обеспечивает требуемую задержку команд.
  • Выбран строгий приоритет с заменой устаревших состояний.
  • Аварийная команда имеет наивысший приоритет.
  • Скорость 260 кбит/с практически полностью загружена.
  • При 230 кбит/с видеоданные накапливаются и устаревают.
  • Итоговое восстановление всех кадров после освобождения очереди не означает работу видео в реальном времени.
  • Расчёты и графики выполнены с Matplotlib 3.11.1.
  • Следующий этап посвящён отбрасыванию устаревших видеокадров.

Запись 009

Дата

3 августа 2026 года

Тема

Завершение Lab034: реактивное отбрасывание устаревших видеокадров.

Выполнено

  • Сравнены непрерывные FEC-блоки и блоки, выровненные по составным кадрам.
  • Выравнивание увеличивает видеопоток на 5,975 кбит/с, или на 2,633%.
  • При 300 кбит/с удаление кадров не требуется.
  • При 260 кбит/с ограничения 1000 и 1500 мс не срабатывают, а ограничение 500 мс уже чрезмерно.
  • При 230 кбит/с реактивное удаление устаревших кадров уменьшает очередь, но резко снижает частоту обновления.
  • Ограничение 500 мс оставляет только 3 из 63 кадров.
  • Ограничение 1500 мс оставляет 27 из 63 кадров.
  • Подтверждено, что короткая очередь сама по себе не означает свежее изображение.
  • Текущая реактивная политика не принята.
  • Следующий этап посвящён упреждающему допуску кадров и обслуживанию видео целыми кадрами.

Запись 010

Дата

3 августа 2026 года

Тема

Завершение Lab035: упреждающий допуск и обслуживание видео целыми составными кадрами.

Выполнено

  • Lab035 исследует упреждающий допуск и обслуживание видео целыми составными кадрами.
  • Начатый кадр всегда передаётся полностью.
  • Команды и телеметрия могут передаваться между его пакетами.
  • Реактивное удаление Lab034 окончательно не принято.
  • Основная политика — хранение только самого свежего не начатого кадра.
  • При 230 кбит/с опубликовано 56 из 63 кадров с частотой около 2,6 кадра/с.
  • Бесполезно переданных видеобайтов нет.
  • Очередь из двух кадров увеличивает возраст изображения.
  • Прогноз 1000 мс не дал преимущества над более простой политикой.
  • Прогноз 500 мс чрезмерно снижает частоту обновления.
  • Следующая лабораторная проверяет долговременную устойчивость и изменение пропускной способности канала.

Запись 011

Дата

3 августа 2026 года

Тема

Завершение Lab036: долговременная устойчивость видеопланировщика при изменении пропускной способности.

Выполнено

  • Lab036 проверяет видеопланировщик на протяжении 600 секунд.
  • Расчётный рост очереди без удаления совпал с моделью.
  • При 230 кбит/с очередь без удаления выросла до 4139 пакетов.
  • 95-й процентиль возраста изображения достиг 74,6 секунды.
  • Плавное поступление сильно устаревших кадров непригодно для управления.
  • Политика хранения только самого свежего не начатого кадра ограничивает очередь.
  • При 230 кбит/с она обеспечила около 2,615 кадра/с.
  • После восстановления скорости возраст изображения снизился ниже 500 мс за 0,077 секунды.
  • Политика двух ожидающих кадров оставлена резервной.
  • Следующая лабораторная объединяет планировщик с моделью ошибок радиоканала и защитой команд управления.

Запись 012

Дата

4 августа 2026 года

Тема

Завершение Lab037: полный транспорт с серийными потерями и повторением критических команд.

Выполнено

  • Lab037 объединяет видеопоток, обычные и аварийные команды, телеметрию и временные серийные потери пакетов.
  • Близкие повторные копии команд часто попадают в один и тот же интервал помехи.
  • Повторение Lab037 лишь умеренно уменьшило долю недоставленных управляющих состояний.
  • Максимальный промежуток без свежей команды остался более одной секунды.
  • Своевременная доставка аварийной команды по радиоканалу не гарантируется.
  • Для безопасного поведения при потере связи требуется локальный сторожевой таймер на ровере.
  • Следующий этап исследует сторожевой таймер, временно разнесённую аварийную команду и подтверждение получения.

Запись 013

Дата

4 августа 2026 года

Тема

Завершение Lab038: локальный сторожевой таймер и подтверждаемая аварийная команда.

Выполнено

  • Lab038 исследует локальный сторожевой таймер, разнесённую аварийную команду и подтверждение получения.
  • Три инварианта безопасности не нарушены ни разу.
  • Подтверждение не является условием выполнения аварийной остановки.
  • Режим с подтверждением сохранил итоговую доставку аварийной команды 99,694%.
  • Среднее число аварийных копий уменьшилось с 11 до 1,071.
  • Дополнительная нагрузка подтверждаемого режима составляет около 0,0093 кбит/с.
  • Дополнительное повторение обычных команд не принято как основной режим.
  • Порог 100 мс вызывает слишком частые безопасные остановки.
  • Порог 500 мс допускает слишком большой путь до реакции.
  • Для следующей проверки принята двухступенчатая логика: предварительная реакция после 150 мс и обязательная остановка после 250 мс.

Запись 014

Дата

5 августа 2026 года

Тема

Завершение Lab039: двухступенчатая безопасная реакция и оценка пути до остановки.

Выполнено

  • Lab039 реализует состояния NORMAL, STAGE1_DECELERATION, STAGE2_BRAKING и EMERGENCY_LATCHED.
  • Используется точное событийное интегрирование движения.
  • Аналитические значения совпали с моделью с нулевой ошибкой.
  • Максимальный полный путь составил 13,9642 м.
  • При 25 км/ч и номинальном профиле политика 150/250 мс дала полный путь около 9,5388 м.
  • Основную часть пути составляет торможение после реакции.
  • Пара 150/250 мс сохраняется как предварительный кандидат, но окончательно не утверждается.
  • Фактические замедления должны быть измерены на реальном ровере.
  • Локальный сторожевой таймер сохранил безопасную реакцию в опытах, где аварийная команда не была доставлена.
  • Следующий этап исследует постоянное аварийное намерение наземной станции и безопасное разрешение повторного движения.

Запись 015

Дата

5 августа 2026 года

Тема

Завершение Lab040: постоянное аварийное намерение и безопасное повторное разрешение движения.

Выполнено

  • Lab040 реализует постоянное аварийное намерение наземной станции.
  • Ограниченное окно повторения 500 мс признано небезопасным.
  • При полностью потерянной аварийной передаче ограниченный режим допускал последующее возобновление движения.
  • В одном из тяжёлых условий путь после такого восстановления достигал в среднем около 490 м при 25 км/ч.
  • Постоянное аварийное намерение исключило положительные задания скорости и небезопасные возобновления движения.
  • Подтверждение аварийной команды не снимает аварийное намерение.
  • Сброс принимается только после остановки, при свежей связи и корректных идентификаторах.
  • Подтверждение сброса не восстанавливает старую команду движения.
  • Движение требует новой явной команды оператора.
  • Следующий этап посвящён сеансам связи, перезапускам устройств и защите от пакетов предыдущего сеанса.

Запись 016

Дата

5 августа 2026 года

Тема

Завершение Lab041: сеансы связи, безопасный запуск и защита от пакетов предыдущего сеанса.

Выполнено

  • Lab041 вводит идентификаторы сеанса станции, запуска ровера и периода управления.
  • Одного номера сообщения недостаточно после перезапуска.
  • В основном режиме все 2807 введённых старых пакетов были отклонены.
  • Ошибочно принятых старых пакетов не было.
  • Исходный режим без идентификаторов принял все старые пакеты.
  • После перезапуска движение запрещено до нового согласования, подтверждения разрешения и новой команды оператора.
  • Аварийное намерение наземной станции сохраняется после перезапуска.
  • Неоднозначная разность номеров 2^31 отклоняется.
  • Следующий этап посвящён криптографической проверке подлинности управляющих сообщений и защите от намеренной подделки.

Запись 017

Дата

7 августа 2026 года

Тема

Аудит достоверности Lab041 и удаление показателей, не выводимых из модели. Начало этапа стабилизации после Lab041.

Причина записи

Запись 016 не отменяется, но нуждается в уточнении. Машинный аудит репозитория показал, что часть числовых результатов Lab041 не выводилась ни из модели этой лабораторной, ни из указанного источника. Согласно правилу журнала прежняя запись сохранена, а изменение зафиксировано отдельно.

Что обнаружено

  • В функции simulate_trial доли публикации видео, доставки телеметрии и доставки управления, а также базовая длина очереди задавались вписанными таблицами, а не вычислялись.
  • Значение доли видео 0,910 для канала 260 кбит/с не соответствовало заявленному источнику: Lab040 даёт 0,9603, Lab037 — разброс 0,9026...0,9174.
  • Базовая длина очереди 31 для того же канала не соответствовала Lab040, где получено 36...38 пакетов.
  • Коэффициенты влияния нагрузки 0,15, 0,10 и 0,05 не выводились ни из какой модели.
  • Параметры торможения были зашиты литералами 0.250 и делителем 6.0 без связи с профилем nominal Lab039, откуда они происходят.
  • Пять из четырнадцати инвариантов безопасности не измерялись: два вычислялись выражением с умножением на ноль, один был литеральным нулём, ещё два опирались на поля, которые никогда не заполнялись. Проверка validate_outputs подтверждала эти константы, то есть проверяла тождество.
  • Формулировка «все 2807 введённых старых пакетов были отклонены» описывает перебор таблицы сценариев, а не измеренную вероятность отклонения. Число раскладывается как семь сценариев на 401 повтор.

Выполнено

  • Из Lab041 удалены четыре показателя: доли доставки видео, телеметрии и управления и максимальная длина очереди. Они относятся к Lab037 и Lab040 и в Lab041 не моделируются.
  • Удалён график lab041_traffic_impact.png, потерявший основание. Осталось семь графиков.
  • Удалены поля negative_speed_cases и speed_limit_exceeded_cases, которые никогда не вычислялись, и тождественные проверки в validate_outputs.
  • Параметры торможения связаны с профилем nominal Lab039 через именованные константы LAB039_NOMINAL_STAGE2_MPS2 и LAB039_STAGE2_THRESHOLD_SECONDS; горизонт незащищённого движения выделен как явно принятое допущение.
  • Перенесённые величины VIDEO_OFFERED_LOAD_KBPS и TELEMETRY_OFFERED_LOAD_KBPS снабжены указанием источника: Lab038, поля video_load_kbps и telemetry_load_kbps.
  • Секция инвариантов переписана: девять свойств, следующих из архитектуры, снабжены ссылками на подтверждающие функциональные проверки; пять свойств, которые матрица не может измерить, вынесены в отдельный раздел со ссылками на проверки 04, 06, 07, 10, 16 и 19.
  • В отчёт добавлено разграничение того, что моделируется розыгрышем, что задано архитектурой и что не моделируется вовсе.
  • Проверка 04 расширена отрицательной скоростью и границей 15 м/с, поэтому соответствующее свойство теперь подтверждается реально, а не константой.
  • Оценка пути после перезапуска помечена как расчёт по замкнутой формуле, одинаковый во всех повторах, а не как результат розыгрыша.

Результат

  • Lab041 перезапущена полностью: 180 сочетаний, 24 из 24 функциональных проверок пройдены, пять CSV и семь PNG.
  • Сверка с прежними файлами показала, что удалено ровно шесть столбцов, а все сохранённые значения совпали до последнего знака. Расхождений в общих столбцах ноль.
  • Научные выводы Lab041 не изменились. Максимальный путь после перезапуска остался 9,7737 м, постоянная нагрузка управления 10,88000 кбит/с, полный предложенный поток 262,076 кбит/с.
  • Выводы Записи 016 о сеансах, безопасном запуске и отклонении старых пакетов остаются в силе. Уточняется их основание: доказательством служат 24 функциональные проверки, работающие с настоящими автоматами, а не счётчики матрицы из 180 сочетаний.

Следующий этап

Криптографическая аутентификация отложена. Сначала выполняется этап стабилизации: быстрые тесты protocol/ вместо единственной точки входа через лабораторную, разделение быстрых проверок и экспериментов, воспроизводимое описание окружения.


Запись 018

Дата

10 августа 2026 года

Тема

Выбор радиочастотной архитектуры: рабочий диапазон, скачки по частоте и меры против подавления.

Исходные данные

  • Устройство опрошено напрямую: Analog Devices PlutoSDR Rev.C (Z7010-AD9361). Приёмник перестраивается от 70 МГц до 6 ГГц, передатчик от 46,9 МГц. Минимальная частота дискретизации 2 083 333 Гц.
  • Ограничений по разрешённым частотам у проекта нет.
  • Усилителя мощности нет, покупка отложена до первых испытаний.

Отвергнутые варианты и причины

Выбор редкой фиксированной частоты. Рассматривался как защита от подавления. Отклонён: одиночная несущая в пустом эфире обнаруживается сканирующим приёмником тривиально. Уязвимость создаёт не значение частоты, а её неизменность.

Скачки по всему диапазону 70 МГц – 6 ГГц. Теоретически требуют от заградительной помехи на 42 дБ больше мощности, но выигрыш недостижим. Отношение крайних частот 86:1, одна антенна такой полосы не перекрывает; разброс потерь на 10 км составляет 39 дБ, проектировать пришлось бы по худшему краю; выше примерно 1 ГГц дифракция исчезает и для наземного ровера без прямой видимости эти каналы мертвы. Кроме того, подавление направлено на диапазон, в котором связь действительно работает, а не на тот, который способно настроить оборудование.

Диапазоны 330–433 МГц. Отклонены как плотно занятые и общеизвестные.

Принято

Рабочий диапазон 200–250 МГц. Обоснование: четвертьволновая антенна 33 см пригодна для установки на ровер, дифракция ещё эффективна, участок заметно свободнее любительского 144 МГц и УКВ выше 300 МГц. Потери на 10 км составляют около 99,5 дБ.

Совокупность мер против подавления:

  1. Скачки по частоте в пределах 200–250 МГц. Требуют от заградительной помехи на 22 дБ больше мощности при неизменной антенне и механике ровера.
  2. Направленная антенна наземной станции. Даёт 10–20 дБ усиления и пространственно подавляет помеху, приходящую с иного направления.
  3. Расширение спектра для команд управления. Поток команд составляет 10,88 кбит/с, поэтому расширение для него реализуемо в узкой полосе, в отличие от видеопотока.

Видео остаётся некритичным классом: при подавлении управление сохраняется в узкой полосе, а ровер переходит к безопасному поведению по уже реализованной логике.

Запрещённые участки

  • 108–137 МГц — авиационная связь.
  • 243 МГц — международная аварийная частота.

Ограничения решения

  • Нижняя граница 70 МГц определяется приёмником Pluto и без смены оборудования не преодолевается.
  • Скачки требуют согласованной последовательности у обеих сторон, то есть зависят от криптографической аутентификации, которая пока не реализована.
  • Расчёты выполнены для свободного пространства. Потери на препятствиях 20–40 дБ учтены оценочно и подлежат измерению.
  • Дальность 10 км без усилителя мощности не достигается.

Влияние на ближайшие работы

На Lab042 не влияет: там кабельная петля, несущая 435 МГц выбрана произвольно. Диапазон 200–250 МГц вступает в силу начиная с эфирных испытаний.


Запись 019

Дата

10 августа 2026 года

Тема

Lab042: первая передача изображения через реальный радиотракт. Эфирная проверка на паре антенн.

Причина эфирного прогона

Кабельная петля требует переходника SMA папа-папа, которого пока нет: пигтейлы к антеннам оканчиваются папой, а разъёмы Pluto — мамы. Чтобы не простаивать, выполнена вспомогательная эфирная проверка на двух антеннах, разнесённых на 60 см. Она не заменяет кабельный опыт: уровни в помещении не контролируются строго, возможны переотражения. Её задача — снять последнюю неизвестность в коде, а именно обвязку вокруг устройства, которая в моделях не проверяется.

Условия

  • Устройство Analog Devices PlutoSDR Rev.C, чип AD9361, прошивка v0.32.
  • Несущая 225 МГц, внутри целевого диапазона Записи 018.
  • Антенны, рассчитанные на 108 МГц, работают на несущей как полуволновые. Частота передачи и частота, на которую рассчитана антенна, различны, поэтому в авиационный диапазон 108–137 МГц опыт не заходит.
  • Изображение 320x180 в градациях серого, JPEG 4756 байт при качестве 35, десять фрагментов.

Результат

  • Изображение передано и собрано побайтово идентично исходному. Контрольная сумма MD5 переданного и принятого файла совпала.
  • Десять фрагментов из десяти, ни одной несошедшейся контрольной суммы.
  • Средняя нормированная корреляция при поиске кадра 0,99951.
  • Средняя оценка ухода несущей минус 0,368 Гц, что отражает общий опорный генератор передатчика и приёмника.
  • Канальная скорость 18,404 кбит/с при длительности сигнала в эфире около 2,07 секунды.
  • Результат воспроизведён тремя запусками подряд с одинаковой контрольной суммой.

Дефекты, вскрытые железом

Программная модель проходила чисто, но на устройстве обнаружились четыре дефекта, каждый воспроизведён и устранён.

  • Кадр длиной 566 528 отсчётов не помещался в приёмный буфер 262 144. Между отдельными чтениями поток отсчётов не является непрерывным, и кадр на стыке разрушался. Приём переведён на один буфер, размер которого рассчитывается по длине кадра.
  • Частотная коррекция применялась всегда, тогда как при общем опорном генераторе истинный уход близок к нулю. Оценка по маркеру длиной 80 символов состояла из шума, и коррекция им поворачивала фазу вдоль всего кадра: измерено 65 процентов ошибочных битов. Перенесена защита should_apply_cfo_correction из Lab023, разрешающая коррекцию только вне мёртвой зоны.
  • Усиление приёмника 20 дБ давало сигнал около 0,0003 от шкалы АЦП. Рабочие уровни подобраны измерением: приёмник 50 дБ, передатчик минус 10 дБ дают ноль ошибочных битов с запасом.
  • Величина вектора ошибки при неудачном приёме возвращала ноль, то есть показывала идеальный сигнал там, где сигнала не было. Это тот же класс ошибки, что вписанные показатели Lab041: метрика при отказе рапортует лучшее значение. Заменена на явный признак невычислимости.

Ограничения

  • Эфирный прогон является проверкой тракта, а не измерением: уровни не контролируются как в кабельной сборке.
  • Потолок усиления передатчика в эфирном режиме рассчитывается из бюджета линии по расстоянию между антеннами, а не задан константой.

Следующий этап

Кабельная петля через аттенюатор 30 дБ после получения переходника папа-папа. Это и есть заявленный опыт Lab042 с контролируемыми уровнями, его результат станет основным для лабораторной. Затем Lab043 — разведение на два устройства.


Запись 020

Дата

11 августа 2026 года

Тема

Lab042 завершена: кабельная петля через аттенюатор, зависимость доставки от мощности, устранение трёх дефектов отчётности.

Схема опыта

Выход передатчика PlutoSDR через кабель SMA, аттенюатор AT30S 30 дБ, переходник и второй кабель на вход приёмника того же устройства. Антенны сняты. Это заявленный основной опыт лабораторной с контролируемыми уровнями, в отличие от вспомогательной эфирной проверки Записи 019.

Зависимость доставки от мощности передатчика

Кабельный тракт при неизменной схеме исследован по усилению передатчика. Получен отчётливый переход от отказа к устойчивой передаче:

  • TX минус 30 дБ: 0 из 10 фрагментов, контрольная сумма не сходится ни разу, средняя корреляция 0,936. Сигнал ниже порога уверенного приёма.
  • TX минус 20 дБ: 8 из 10 фрагментов, средняя корреляция 0,992. Пограничный режим: часть кадров проходит.
  • TX минус 10 дБ: 10 из 10 фрагментов, изображение собрано побайтово. Устойчивая передача.

Значения TX минус 30 и минус 20 дБ — исследование порога, повторять их не требуется. Рабочая точка кабельной петли: TX минус 10 дБ, RX плюс 20 дБ, аттенюатор 30 дБ, несущая 435 МГц.

Начальные умолчания кабельного режима TX минус 30 и RX плюс 20 дБ на железе прежде не проверялись; отказ первого прогона объяснялся именно этим, а не дефектом обработки.

Результат рабочей точки

  • Найдено 10 кадров из 10, контрольная сумма сошлась у всех десяти, восстановлены все фрагменты.
  • Изображение собрано и совпадает с переданным. Совпадение подтверждено независимо: SHA-256 принятого файла сверен с SHA-256 переданного JPEG, пересобранного из исходника отдельно от прогона. Оба равны 751d7ea0d8711e2ef54fc5cf209a809cfee5bbb14916dd20aa201d5285b40286.
  • Размер JPEG 4756 байт, качество 30, десять фрагментов.
  • Длительность сигнала около 2,07 секунды, канальная скорость 18,404 кбит/с.
  • Кадр 8 прошёл контрольную сумму при пониженной корреляции поиска 0,866 против 0,998 у остальных: низкая корреляция маркера не означает испорченных данных, фаза дискретизации была подобрана и кадр демодулировался чисто.

Устранённые дефекты отчётности

Разбор кабельного прогона вскрыл три дефекта, при которых провал мог быть принят за успех. Все три устранены, каждый закрыт быстрым тестом в tests/test_lab042_reporting.py.

  • Величина вектора ошибки нормировалась на единичный эталон, из-за чего при слабом сигнале становилась искусственно малой: провалившийся прогон показывал EVM меньше, чем успешный. Нормировка исправлена на мощность подогнанного сигнала. При невозможности вычислить величину возвращается признак невычислимости, а не ноль.
  • Отчёт перечислял lab042_received.jpg среди созданных файлов безусловно, даже когда изображение не собрано и файла нет. Теперь файл указывается только при фактической сборке.
  • Программа завершалась кодом ноль при полном отказе передачи. Введён критерий приёмки: при несобранном изображении код завершения ненулевой, чтобы автоматика не приняла провал за успех.

Проверки

  • Быстрые тесты ядра расширены с 125 до 135. Добавленные проверяют неуспешный путь: провал даёт ненулевой код, отсутствующий файл не объявляется созданным, невычислимая метрика не превращается в ноль.
  • Окончательный кабельный прогон рабочей точки выполнен уже исправленной версией программы, поэтому итоговый отчёт сформирован ею.

Следующий этап

Lab043: передаёт PlutoSDR, принимает RTL-SDR. Общий опорный генератор исчезает, впервые появляется реальное рассогласование несущей и частоты дискретизации двух независимых устройств. Здесь понадобится защищённая частотная коррекция, перенесённая в Записи 019.

Запись 021

Дата

31 августа 2026 года

Тема

Lab044 (произвольный protocol packet через реальный BPSK HackRF-канал): implementation prepared, hardware validation pending.

Статус

Lab044 implementation prepared. Hardware experiment NOT YET RUN, RF TX count = 0. Реализация построена поверх рабочей точки Lab043 (checkpoint 4cee6e9) без изменения её RF-параметров, gain, PHY sync, PRBS7-преамбулы, CRC или независимого детектора. Три пробела, найденные аудитом (отсутствие теста на обрезанный protocol packet, отсутствие BEFORE/DURING/AFTER диагностики записи, отсутствие SHA-256 для всех бинарных RX/TX артефактов), закрыты и покрыты новыми тестами. Подробности — в docs/lab044_current_state.md.

Следующий этап

Реальный аппаратный RF-прогон Lab044 (ровно один TX) должен выполнить локальный агент после полного PASS python tools/quick_gate.py и python -m pytest tests/ -q на машине с подключённым HackRF.

Запись 022

Дата

31 августа 2026 года

Тема

Lab044: первый реальный аппаратный RF-прогон произвольного protocol packet через BPSK HackRF-канал (ровно один TX).

Выполнено

Software gate пройден полностью на рабочем интерпретаторе машины (Python 3.13.1, numpy 2.2.6, scipy 1.18.0, pytest 9.1.1): python -m pytest tests/ -q = 373 passed, 0 failed, 0 skipped; python tools/quick_gate.py = OK; git diff --check чист. Выполнен ровно один аппаратный RF-эксперимент python experiments/lab044_hackrf_bpsk_packet.py --hardware --i-understand-hardware. RF TX count = 1, без retry.

Common-clock preflight PASS: MASTER reg29 = 0x26, SLAVE reg29 = 0x26, SLAVE CLKIN = DETECTED за 69 мс (bounded polling 0.05/0.05/0.5 с). RX стартовал до TX. Логи TX/RX чистые: 0 underruns, 0 overruns. Clipping 0, перегрузки АЦП нет.

Результат — RESULT C, CRC NOT_REACHED (CRC не PASS). Независимый PRBS7-детектор нашёл преамбулу (peak/median +38.3 dB), PHY SYNC 0xD391 восстановлен верно. Physical-layer BER по преамбуле ≈ 0.625 % (8/1280), согласуется с Lab043. Но одиночные битовые ошибки попали в поля длины: PHY LENGTH декодировано 264 вместо 268 байт, а protocol payload_length — 2304 вместо 256, из-за чего protocol header дал PAYLOAD_LENGTH_MISMATCH и разбор пакета сорвался раньше CRC. Protocol SYNC 0xAA55, version, message type (TELEMETRY), sequence (44) при этом декодированы верно. Packet/payload BER не вычислялись как «после успешного decode»: RX-пакет 264 байта не сопоставим с TX 268 байт, rx_payload.bin не создан. SNR 7.19 dB, separation 4.574, CFO 0.101 Hz (общий опорник). Артефакты: C:\Users\user\Documents\SDR_Rover_Lab044_raw\20260831_140142_bpsk_packet\, SHA-256 всех реально созданных бинарных файлов пересчитаны независимо и совпали с metadata.json; фиктивный rx_payload.bin не создавался (SHA = null). Cleanup: MASTER/SLAVE CLKOUT OFF, зависших hackrf_transfer.exe нет. Пост-RF software gate повторно пройден (373 passed). Изменения ещё не коммитятся: сначала результат смотрит ChatGPT. Подробности и таблица BEFORE/DURING/AFTER — в docs/lab044_current_state.md.

Следующий этап

Защитить критические поля кадра от одиночных битовых ошибок при BER ~0.6 %: FEC либо избыточное/помехоустойчивое кодирование PHY LENGTH и protocol-заголовка (ошибка сорвала разбор именно в длине, а не в CRC полезной нагрузки). Только после этого имеет смысл повторный аппаратный прогон Lab044 и переход к более длинным/структурированным передачам.

Запись 023

Дата

31 августа 2026 года

Тема

Lab045: программная подготовка bit-level FEC для реального BPSK-пакета.

Выполнено

Реализован свёрточный код R=1/2, K=7 с многочленами 171 и 133 octal, нулевым начальным состоянием и шестью нулевыми tail bits. Soft-decision decoder Витерби использует евклидову branch metric по вещественным BPSK-решениям до hard slicing. Соглашение BPSK сохранено от существующего тракта: бит 0 соответствует минус 1, бит 1 соответствует плюс 1.

Добавлен детерминированный блочный interleaver с записью строками и чтением столбцами. Перестановка не теряет элементы на неполной последней строке, проверяется как полная биекция и одинаково применяется к coded bits и soft values. Существующий GF(256) erasure FEC 12+3 не менялся и остаётся механизмом более высокого уровня для известных потерянных fragments.

Весь существующий protocol packet длиной 268 байт, включая 8-байтовый заголовок, 256 байт произвольного payload и CRC32, преобразуется в 2144 information bits и кодируется вместе с шестью tail bits в 4300 coded bits. Protocol parser вызывается только после deinterleave и soft Viterbi; существующий CRC32 остаётся независимым end-to-end решением.

PHY header расширен до magic, версии, длины packet и 8-битного checksum. Его 48 бит защищены побитовым повторением b,b,b до 144 бит. Majority decoder fail-closed проверяет magic, версию, checksum, предел длины и наличие рассчитанного числа coded symbols до запуска FEC decoder.

Подготовлен IQ-адаптер поверх доказанного Lab044: независимый PRBS7 detector, timing, CFO и phase/polarity recovery переиспользуются без TX payload, а FEC получает normalized.real до hard slicing. Диагностическое сравнение с TX разрешено отдельной функцией только после независимого CRC verdict.

Точный кадр Lab045 содержит 5724 BPSK-символа. При 400 samples per symbol и существующих guard/RRC параметрах Lab044 форма содержит 2 306 400 samples и длится 288,3 мс при 8 MS/s. Для сравнения Lab044 содержал 3456 символов, 1 399 200 samples и 174,9 мс.

Синтетический software-тракт прошёл. В детерминированном опыте с 28 ошибками из 4300 coded bits, BER 0,6512 процента, после FEC осталось 0 ошибок protocol packet, CRC PASS и payload восстановлен точно. Пачка из 14 соседних channel symbols также исправлена. Отдельный AWGN-тест подтвердил реальное использование soft-амплитуд: soft Viterbi дал 0 information-bit errors, тогда как hard baseline по тем же значениям дал 5.

Полный программный шлюз: python tools/quick_gate.py PASS, python -m pytest tests/ -q дал 417 passed, 0 failed, 0 skipped, git diff --check чист. Подробности, формат кадра и ограничения записаны в docs/lab045_current_state.md.

Аппаратные утилиты в этой сессии не запускались. RF TX = 0, RF RX = 0, hardware validation не выполнялась. Git add, commit и push не выполнялись.

Следующий этап: после отдельного разрешения подготовить ограниченный аппаратный runner Lab045 на базе common-clock preflight, one-TX guard, артефактов и cleanup Lab044, повторно пройти software gate и только затем рассматривать один аппаратный FEC-прогон.

Запись 024

Дата

1 сентября 2026 года

Тема

Lab045: первый аппаратный RF-прогон bit-level FEC — RESULT A, реальная помехоустойчивая коррекция в эфире доказана.

Выполнено

Перед эфиром исправлена устаревшая цифра в Записи 023 (414 → 417 passed) и в документации явно разделены две величины: информационные символы кадра (5724 символа, 2 289 600 отсчётов, 286,2 мс) и фактически сгенерированная форма сигнала (2 306 400 отсчётов, 288,3 мс). Разница в 42 символа (16 800 отсчётов) подтверждена прямо по формирователю shape_frame_like_lab042: 32 нулевых защитных символа (guard, по 16 с каждой стороны) плюс 10 символов длины корневого приподнятого косинуса (переходный хвост фильтра, режим full). Это учётная величина, а не дефект сигнала; форма не менялась. Тот же механизм даёт 1 399 200 отсчётов в Lab044.

Программный шлюз перед эфиром: quick_gate PASS, pytest 417 passed, git diff --check чист. Обе платы видны, серийники соответствуют ролям.

Выполнен ровно один аппаратный прогон python experiments/lab045_hackrf_bpsk_fec.py --hardware --i-understand-hardware. RF TX count = 1, без повторов. Рабочая точка Lab043/Lab044 без изменений: RF 1080 МГц, 8 MS/s, BPSK 20 ксимв/с, digital carrier +50 кГц, TX VGA 10 дБ, RX LNA/VGA 24/24 дБ, RF amp и bias OFF. Общий опорник: MASTER reg29 = 0x26, SLAVE reg29 = 0x26, SLAVE CLKIN = DETECTED (за 2 опроса, 141,8 мс). RX стартовал до TX; логи TX/RX чистые: 0 overruns, 0 underruns; clipping 0.

Результат — RESULT A с флагом REAL RF FEC CORRECTION DEMONSTRATED = YES. Канал в этом прогоне оказался существенно шумнее рабочей точки Lab044: SNR всего 2,63 дБ, ошибок преамбулы 39/1280 (3,05 %). Независимый приёмник (детектор преамбулы, timing, CFO, phase/polarity, мажоритарный PHY header) без доступа к переданным данным извлёк мягкие BPSK-значения. Диагностическое сравнение с TX, разрешённое только после независимого CRC-решения, показало 155 ошибок из 4300 кодированных бит (BER 3,60 %) до FEC. После deinterleave и мягкого декодера Витерби: 0 ошибок пакета (0/2144), 0 ошибок payload (0/2048), 0 байтовых ошибок. CRC PASS, protocol header корректен (SYNC 0xAA55, версия 1, тип 2, sequence 44, payload_length 256). Восстановленный 256-байтный произвольный payload побитово точен: SHA-256 rx_payload.bin совпал с tx_payload.bin (cb9d06fe…), rx_packet.bin совпал с tx_packet.bin (ed5a5713…). Это прямое доказательство: при SNR 2,63 дБ незащищённый пакет Lab044 не прошёл бы CRC, а свёрточный код R=1/2 K=7 с мягким Витерби исправил все реальные ошибки эфира.

Артефакты: C:\Users\user\Documents\SDR_Rover_Lab045_raw\20260901_103434_bpsk_fec\. SHA-256 всех реально созданных бинарных файлов вычислены дважды и совпали; фиктивных файлов не создавалось. Cleanup: MASTER/SLAVE CLKOUT OFF (SLAVE CLKIN «no clock signal detected»), зависших hackrf_transfer нет. Пост-RF шлюз повторно пройден: quick_gate PASS, pytest 417 passed, git diff --check чист. Второй TX не выполнялся. Git add/commit/push не выполнялись: результат сначала смотрит ChatGPT.

Следующий этап

Проанализировать первый аппаратный результат Lab045 (в частности, почему SNR упал до 2,63 дБ против 7,19 дБ в Lab044 — вероятно антенна/связь/положение) и по решению ChatGPT определить, что дальше: закрепление рабочей точки, переход к более длинным/структурированным передачам или к сжатому изображению. Ни FEC/QPSK/JPEG/video, ни второй TX в этой сессии не запускаются.

Запись 025

Дата

1 сентября 2026 года

Тема

Lab046: многопакетная передача большого бинарного объекта — только программно, RF TX = 0, аппаратная проверка не проводилась.

Выполнено

Статус: SOFTWARE VALIDATED. RF TX = 0. HARDWARE VALIDATION = NOT PERFORMED. HackRF и hackrf_transfer не запускались; ни JPEG, ни видео, ни QPSK.

Сначала аудит. Установлено, что оба нужных уровня уже есть: protocol/image_fragments даёт семантику фрагмента (object_id, индекс, число фрагментов, общий размер) и fail-closed reassemble_image, а Lab045 даёт кадр целиком (build_transmission_plan, analyze_post_preamble_soft, simulate_soft_channel, диагностика pre/post-FEC). Отдельный модуль формата фрагмента не создавался — переиспользован 12-байтовый заголовок image_fragments (>IHHI). Два уровня строго разделены: уровень 1 (внутри кадра) — свёрточный код R=1/2 K=7 + перемежитель + мягкий Витерби + CRC (Lab045); уровень 2 (объект) — фрагментация/нумерация/сборка. Erasure-код 12+3 GF(256) protocol/packet_erasure_fec НЕ использован и НЕ изменён (остаётся будущим расширением для потери целых фрагментов, а не для битовых ошибок).

Минимальный новый слой в experiments/lab046_bpsk_object_transport.py: упаковка фрагмента в 256-байтную нагрузку Lab045 (FRAGMENT_DATA_SIZE = 256 − 12 = 244) с обрезкой добивки на приёме по длине из полей заголовка (expected_fragment_data_length) и fail-closed ObjectAssembler (offer возвращает accepted/duplicate/conflicting/rejected, никогда не бросает). Приёмник без оракула: TX-объект/TX-биты не используются для приёма, FEC, метаданных и решения о завершении; сравнение с оригиналом — только в диагностике после независимого CRC и независимой сборки. При недостающем/повреждённом фрагменте OBJECT COMPLETE = NO и recovered_object = None, фиктивный объект не создаётся. original_size проверяется на обе границы, чтобы поле не управляло размером аллокаций.

Детерминированный объект 16384 байта (16 KiB, не JPEG; numpy default_rng(seed=46)), SHA-256 748013b5…3408d515; в Git не добавлялся. Разбит на 68 фрагментов, последний короткий (36 байт данных). Метрики (идеальный канал): протокольный пакет 268 байт, 68 BPSK-кадров, 389 232 информационных символа (5724 × 68), 156 835 200 отсчётов формы (2 306 400 × 68), эфирное время 19,60 с, полезный goodput 835,7 байт/с = 6,69 кбит/с (≈0,337 полезного бита на символ). Накладные расходы: фрагментация 12 байт/пакет (816 байт), протокольный header+CRC 12 байт/пакет (816 байт), свёрточный код R=1/2, PHY преамбула+header 1424 бита/кадр, guard/ФРК 42 символо-времени/кадр, добивка последнего фрагмента 208 байт.

Шесть программных сценариев (seed фиксирован): A идеальный — объект точен (CRC 68/0, sha совпал, 0 байт-ошибок); B распределённые битовые ошибки — честный гауссов шум sigma=0.40 даёт 1805 сырых ошибок кодированных бит до FEC, post-FEC 0, все 68 CRC PASS, объект побитово точен (уровень sigma выбран так, чтобы мягкий Витерби исправлял все кадры; при sigma≥0.45 отдельный кадр не декодируется и без erasure-FEC объект неполон — это по сути сценарий E, а не подгон); C приём в обратном порядке — объект точен; D дубликаты кадров — учтены, объект точен; E потерян кадр 1 — OBJECT COMPLETE = NO, кадр 1 в missing, recovered SHA = None; F повреждён кадр 0 (инверсия coded-потока) — CRC FAIL, объекта нет.

Новый набор tests/test_lab046_bpsk_object_transport.py (фрагмент туда-обратно, короткий последний фрагмент, чужой object_id, невозможный индекс, несогласованный счётчик, усечённые и абсурдные метаданные без крупной аллокации, полный тракт PHY A–F, отсутствие оракула, детерминизм/SHA). Один тест на верхнюю границу original_size выявил реальный пробел в expected_fragment_data_length (проверялась только нижняя граница) — добавлена проверка original_size ≤ fragment_count·244. Документация: docs/lab046_current_state.md.

Software gate: quick_gate PASS (438 тестов ядра, 6 функциональных проверок лабораторий выполнено, 13 штатно пропущено); pytest tests/ -q 438 passed, 0 failed, 0 errors, 0 skipped. Единственное предупреждение связано с отсутствием прав на создание .pytest_cache и на результат тестов не повлияло. git diff --check чист. Git add/commit/push до финальной проверки не выполнялись.

Следующий этап

По решению ChatGPT после анализа Lab046: либо оптимизация накладных расходов серии кадров (преамбула/guard на кадр доминируют в goodput), либо подключение erasure-кода 12+3 для восстановления потери целых фрагментов поверх уже готового bit-level FEC, либо аппаратный прогон многопакетной передачи. RF, QPSK, JPEG и видео в этой сессии не запускались.

Запись 026

Дата

1 сентября 2026 года

Тема

Lab046A: continuous multi-frame receive для 16 KiB объекта в одном soft-stream - только программно, RF TX = 0, аппаратная проверка не проводилась.

Выполнено

Статус: CONTINUOUS STREAM VALIDATION = PASS (NORMALIZED SOFT-SYMBOL LEVEL). CONTINUOUS SAMPLE/IQ VALIDATION = NOT PERFORMED. RF TX = 0. HARDWARE VALIDATION = NOT PERFORMED. HackRF, hackrf_transfer, RF RX/TX, QPSK, JPEG и видео не запускались.

Проведён аудит Lab043-Lab046. Установлено, что предыдущий Lab046 уже собирал 16 KiB объект из 68 Lab045 кадров, но делал это по отдельным кадрам из TX-плана и не доказывал поиск нескольких кадров в одном continuous receive stream. Добавлен Lab046A слой в experiments/lab046_bpsk_object_transport.py: приёмник получает только один float32 normalized soft-symbol stream, самостоятельно ищет PRBS7 candidates, fail-closed декодирует защищённый PHY header, вычисляет длину coded body только из принятого header, запускает существующие Lab045 FEC/CRC и передаёт fragment в ObjectAssembler.

TX offsets, список длин кадров, ожидаемое число 68, порядок/индексы TX, исходный объект, TX packets и coded bits scanner-у не передаются. TX-side frame_starts остаётся только в генераторе stream и используется тестами только для постфактум-сравнения после независимого receive. Scanner fail-closed: rejected candidate не останавливает поиск; cursor монотонен; MAX_FRAMES и MAX_SEARCH_ITERATIONS дают явную причину остановки.

Verifier read-only нашёл реальный дефект первого варианта: глобальный non-maximum suppression мог удалить настоящий старт кадра, если перед ним был более сильный ложный PRBS7 peak. Исправление: список candidates теперь содержит все позиции выше порога в порядке stream; повторный decode уже принятого кадра предотвращается только монотонным cursor после accepted frame. Добавлен регрессионный тест test_stronger_false_peak_does_not_delete_overlapping_later_frame.

Фактические continuous-сценарии для детерминированного объекта 16384 байта, SHA-256 748013b5f670c82bd52650be5454555355dbd8528538753df4558f1c3408d515: ideal continuous - candidates 68, valid headers 68, FEC PASS 68, CRC PASS 68/68, fragments 68, complete=True, SHA совпал, 0 байт-ошибок; background до/между/после 37/37/43 soft-символа - valid frames 68, SHA совпал; noisy continuous sigma=0.40 seed=46001 - pre-FEC 1791, post-FEC 0, CRC 68/0, complete=True, SHA совпал; malformed preamble + bad protected header - candidates 71, rejected 3, последующие valid frames 68, complete=True, SHA совпал.

Учёт: 68 фрагментов, 389 232 soft-symbols, 156 835 200 эквивалентных waveform samples, baseline airtime 19,604400 с при 8 MS/s, useful goodput 6,685846 кбит/с. Основной soft stream занимает 1 556 928 байт; correlation scores 1 551 812 байт; cumulative-energy 3 113 864 байта. Полный continuous complex64 IQ stream не материализуется; при 156 835 200 samples он занял бы около 1,17 GiB до временных копий.

Документация обновлена в docs/lab046_current_state.md. Прямой запуск python experiments/lab046_bpsk_object_transport.py --object-size 300 --sigma 0.4 проверен и работает. Software gate после исправлений: python tools/quick_gate.py PASS, python -m pytest tests/ -q 454 passed, 0 failed, 0 errors, 0 skipped, git diff --check чист. Git add/commit/fetch/pull/push не выполнялись.

Следующий этап

Сначала ChatGPT смотрит Lab046A software result. После отдельного явного разрешения можно выбирать следующий шаг: аппаратная проверка многокадровой передачи, оптимизация накладных расходов серии кадров или erasure-FEC для потери целых фрагментов. RF TX, QPSK, JPEG и video автоматически не запускать.

Запись 027

Дата

1 сентября 2026 года

Тема

Lab046B: программная проверка нескольких полных Lab045-кадров в одном непрерывном сыром IQ-потоке, RF TX = 0, аппаратная проверка не выполнялась.

Выполнено

Статус: ПРОГРАММНАЯ ПРОВЕРКА НЕПРЕРЫВНОГО СЫРОГО IQ-ПОТОКА = PASS. RF TX = 0. АППАРАТНАЯ ПРОВЕРКА = НЕ ВЫПОЛНЯЛАСЬ. HackRF, hackrf_transfer, common-clock операции, RF RX/TX, JPEG, video, QPSK, erasure FEC и ARQ не запускались.

Добавлен software-only эксперимент experiments/lab046b_continuous_iq.py. Пять кадров формируются существующим Lab045: protocol packet, convolutional FEC R=1/2 K=7, interleaver, защищённый PHY header, PRBS7, BPSK, RRC и guards. Они размещаются в одном complex64 IQ stream. Приёмный scan_continuous_iq получает только IQ и известные PHY/FEC параметры; TX offsets, длины waveform, payload, packets и coded bits в его API отсутствуют. TX reference используется лишь в отдельной диагностике после независимого CRC PASS.

Первичный поиск переиспользует PRBS7 reference и normalized correlation Lab043/044, но не применяет глобальный mandatory peak/second gate. Все локальные candidates рассматриваются по положению. Для каждого кандидата локально переиспользуются refine start, matched filter, preamble-only timing, CFO, phase/polarity и normalized.real; затем Lab045 выполняет header-driven deinterleave, soft Viterbi и CRC. Cursor монотонен, accepted frame повторно не декодируется, rejected candidate не останавливает поиск, MAX_FRAMES и MAX_SEARCH_ITERATIONS ограничивают работу.

Фактический идеальный stream: 5 waveform, leading 137 samples, gaps 211/353/587/809, trailing 233; всего 11 534 330 complex64 samples = 92 274 640 bytes (88.0 MiB). PRBS7 candidates 32, processed 5, accepted 5, rejected 0, PHY header PASS 5, FEC PASS 5, CRC 5/0. Все обнаруженные sample offsets совпали с TX при постфактум-сравнении; sampling phase modulo 400 = 137/348/301/88/97. Peak/second настоящих кадров около 0 dB, что воспроизводимо показывает непригодность старого глобального критерия для многокадрового решения.

Сценарий CFO/phase/amplitude: внесено 0.2 Hz, 0.7 rad и scale 0.65 без передачи этих истинных значений scanner-у. Медианная независимая оценка 0.200003768 Hz и 0.699634288 rad, полярность восстановлена по PRBS7, CRC 5/0. Комплексный AWGN: seed 46002, финальная sigma=0.17, accepted 5, pre-FEC 0, post-FEC 0, CRC 5/0. Начальная разумная sigma=0.12 также дала 0 pre-FEC ошибок; после одной разрешённой корректировки дальнейшего подбора не было. Результат шума фиксируется честно как успешный IQ receive без нового события FEC correction.

Ложный IQ-кандидат содержит настоящую PRBS7 waveform и неверный protected PHY magic. Получено candidates 11, processed 8, rejected 7; поиск продолжился и следующий настоящий кадр прошёл PHY/FEC/CRC. Добавлены 14 тестов: два и пять реальных IQ-кадров, arbitrary/non-grid start, разные gaps, ровно один приём кадра, tail background/noise, malformed candidate, продолжение поиска, отсутствие TX-oracle API, CFO/phase, deterministic complex noise, monotonic cursor, оба safety limits и регрессия нескольких сильных настоящих пиков.

Независимый read-only verifier подтвердил тракт, отсутствие TX oracle, multi-peak решение, ложный кандидат, численные CFO/phase и размер основного массива; 88.0 MiB относится именно к main IQ array, не к полному peak RSS с FFT/RRC workspace. Software gate: python tools/quick_gate.py PASS (468 тестов, 7 функциональных лаб, 13 штатно пропущено); python -m pytest tests/ -q = 468 passed; git diff --check чист, кроме информационных LF/CRLF notices. Документация обновлена в docs/lab046_current_state.md. Git add/commit/push не выполнялись.

Следующий этап

Сначала ChatGPT анализирует Lab046B. Аппаратную Lab046, JPEG, video, QPSK, 12+3 erasure FEC, ARQ и адаптивную модуляцию автоматически не начинать.

Запись 028

Дата

1 сентября 2026 года

Тема

Подготовка одного непрерывного аппаратного BPSK-сеанса Lab046C без RF-передачи.

Выполнено

Проведён аудит фактических Lab043--Lab046B. Новый радиопротокол не создавался: Lab046C переиспользует общий clock-gate и однократный TX guard Lab043--Lab045, физический FEC/CRC-кадр Lab045, фрагментацию и ObjectAssembler Lab046, локальный многокадровый IQ-поиск Lab046B.

Подготовлен experiments/lab046c_hackrf_bpsk_object.py. Он создаёт новый криптографически случайный объект 16384 байта, последовательно формирует один cs8-файл из 68 waveform без искусственных gaps и фиксирует SHA-256. Расчёт по фактическому коду: 2 306 400 samples на кадр, 156 835 200 samples и 313 670 400 bytes всего, 19,6044 с при 8 MS/s.

Будущий приём запланирован на 24,0 с: 192 000 000 cs8 samples и 384 000 000 bytes. Файл читается через memmap окнами в complex64; RX API не принимает TX offsets, длины waveform, ожидаемые 68 фрагментов, TX packets, coded bits или объект. Завершённость определяется только принятыми метаданными и ObjectAssembler после CRC.

Аппаратная последовательность fail-closed: фиксированные MASTER/SLAVE serial, common-clock gate, RX раньше TX, ровно один вызов guard перед одним TX process, cleanup CLKOUT/processes в finally, без retry. Отдельный --preflight-only не может выполнить TX. Реальный аппаратный Lab046C не запускался, RF TX = 0.

Фактически создан внешний каталог C:\Users\user\Documents\SDR_Rover_Lab046_raw\20260901_145339_bpsk_object. SHA-256 нового tx_object.bin: f7568a5d1a6dc5dd907fa1e971a171578315de740bd6788136f447e409fc6bf8. SHA-256 единого tx_stream.cs8: 8941eb231f1f2f99cde51f3cc5426472dbedf1a61675543e7774faec4b935f5e. Quick gate прошёл 482 теста и 8 функциональных лаб, полный pytest дал 482 passed. Безопасный common-clock preflight без RF TX подтвердил MASTER и SLAVE reg29 0x26, точный SLAVE CLKIN DETECTED за 141,51 мс; cleanup выключил CLKOUT обеих плат, оставшихся hackrf_transfer нет. RF TX count = 0.

Следующий этап: после успешных software gates и безопасного common-clock preflight остановиться и запросить точную отдельную авторизацию на один непрерывный RF TX Lab046C; без неё передачу не выполнять.

Запись 029

Дата

1 сентября 2026 года

Тема

Первый непрерывный аппаратный опыт Lab046C: официальный RESULT C.

Выполнено

После отдельной точной авторизации выполнен ровно один непрерывный RF TX Lab046C без повтора. Передан единый tx_stream.cs8: 68 полных Lab045 waveform, 156 835 200 complex samples, 313 670 400 bytes, 19,6044 с при 8 MS/s. MASTER/TX 000000000000000097c063dc323b97d3, SLAVE/RX 000000000000000097c063dc2e5327d3, RF 1080 МГц, TX VGA 10 дБ, RX LNA/VGA 24/24 дБ, RF amp и bias OFF.

Common-clock gate прошёл: MASTER reg29 0x26, SLAVE CLKIN DETECTED, SLAVE reg29 0x26. Фактический TX длился 19,60632 с и полностью находился внутри RX capture 24,00386 с. TX underruns 0, RX overruns 0; cleanup выключил CLKOUT обеих плат и не оставил процессов hackrf_transfer. RF TX COUNT = 1.

Независимый многокадровый приёмник не использовал TX offsets, packets, coded bits, ожидаемые 68 фрагментов или исходный объект. Его официальный результат: LAB046C HARDWARE RESULT = C, PREAMBLE CANDIDATES = 0, VALID FRAMES = 0, PHY HEADER PASS = 0, CRC PASS = 0, OBJECT COMPLETE = NO. Восстановленный объект не создавался. Рабочий порог PRBS7 оставался 0.65, независимый максимум равен 0.126562; detector, gain, PHY, FEC и Витерби после опыта не менялись.

TX-файл независимо проверен: SHA-256 8941eb231f1f2f99cde51f3cc5426472dbedf1a61675543e7774faec4b935f5e, RMS 44,002775 code (-9,274598 dBFS), peak 70,405966 code, BPSK около +50 кГц. Первый, средний и последний кадры проходят PRBS7, PHY header, FEC и CRC прямо из файла; амплитуда практически идентична успешному Lab045. Дефект TX-файла или runner, объясняющий RESULT C, не найден.

Только после фиксации независимого RESULT C выполнена read-only диагностика с TX reference. Обнаружены следы 68/68 waveform с точным периодом 2 306 400 samples: aligned min/median/max 0.065784/0.089991/0.122379, смещённый контроль median/max 0.004275/0.010075, медианное преимущество 26,46 дБ. Все 68 aligned значений выше максимума контроля. Это доказывает слабое присутствие TX в RX, но не меняет официальный исход: POST-RUN TX-REFERENCE DIAGNOSTIC = 68/68 WAVEFORM TRACES DETECTED; OFFICIAL RESULT CHANGED = NO. OBJECT TRANSPORT PASS и LAB046C COMPLETE SUCCESS не заявляются.

Перед фиксацией результата повторно пройдены software gates: python tools/quick_gate.py PASS, python -m pytest tests/ -q = 482 passed, git diff --check чист, кроме информационных LF/CRLF notices.

Следующий этап определяется отдельной постановкой после анализа RESULT C; повторный RF TX, изменение PRBS7 threshold, gain или detector автоматически не разрешены.

Запись 030

Дата

1 сентября 2026 года

Тема

Lab046C: автономная слабосигнальная обработка исходного RX capture, offline результат FAIL без нового RF.

Выполнено

Исходный аппаратный результат сохранён без изменения: ORIGINAL LAB046C HARDWARE RESULT = C, RF TX COUNT = 1, ORIGINAL HARDWARE RESULT CHANGED = NO. HackRF не запускался, RF TX в этом этапе равен 0, второй аппаратный или offline независимый прогон не выполнялся.

Добавлен отдельный experiments/lab046c_offline_recovery.py. Исторический Lab046B threshold 0.65 и поведение Lab045 не менялись. Новый первый каскад зафиксирован до полного прогона только по фону первых 0,5 с: 99,9-й процентиль локальных PRBS7-максимумов, threshold 0.025011632591485977, median 0.00838765874505043, MAD 0.003039387986063957, 5193 peaks, 6 candidates, 12,0 candidates/s. На независимом контрольном фоне 21--24 с уже фиксированное правило дало 35501 peak, 301 candidate, 100,333333 candidates/s; после этого порог не изменялся.

Выполнен ровно один полный independent pass сохранённых 192 000 000 cs8 samples. API не получал TX stream/object, offsets, ожидаемые 68, fragment order, packets или coded bits. Coarse stage: 291446 local peaks и 3025 candidates. Strict stage обработал все 3025: refinement/timing/carrier PASS 3025, PHY HEADER PASS 0, PHY HEADER FAIL 3025 (MAGIC_MISMATCH), FEC attempts 0, CRC 0/0, valid frames 0. VALID FRAGMENTS = 0, OBJECT COMPLETE = NO, recovered_object.bin не создан. OFFLINE REPROCESSING OF ORIGINAL RX CAPTURE = FAIL; OBJECT RECOVERED = NO.

Только после независимого verdict выполнена TX-reference диагностика. Все 68 реальных стартов имели candidate в пределах +-40 samples; корреляция min/median/max 0.059379209/0.088661019/0.126557365, все выше фиксированного threshold. Однако preamble errors min/median/max 341/430/554 из 1280, PHY-header errors 30/54/81 из 144, SNR -19.282130/-12.829480/-9.195846 dB. Все 68 диагностических заголовков дали MAGIC_MISMATCH. FALSE CRC PASS = 0, independently valid frames matching TX = 0, missed TX frames = 68. Ни один пропущенный кадр не добавлялся обратно в ObjectAssembler.

Производительность: background calibration 0,269617 с, control 1,031204 с, coarse search 7,721316 с, strict processing 836,340048 с, среднее 0,276476 с на кандидат, полный прогон 845,427589 с, то есть 35,226150 длительности 24-секундного capture. RX использован как memmap, coarse block 16 000 000 complex64 samples; консервативная оценка временной памяти 1 545 705 764 байта, strict local window не более 594400 samples / 4 755 200 байт. Полный complex64 capture в память не загружался.

Добавлены 24 теста statistical calibration/control, deterministic weak PRBS7, CRC-only acceptance, ошибок magic/version/checksum/length, FEC/CRC fail, block-boundary ownership, monotonic cursor, safety limits, отсутствия TX oracle и регрессии Lab045/Lab046B. До полного прогона verifier нашёл и помог закрыть fail-open status safety-limit и заниженную оценку памяти; повторная проверка дала чистый pre-run verdict.

Финальный software gate после фиксации offline FAIL: python tools/quick_gate.py PASS, 506 проверок и 9 функциональных лабораторий; python -m pytest tests/ -q = 506 passed. Предупреждение .pytest_cache не повлияло на результат. git diff --check чист, кроме информационных LF/CRLF notices. Финальный read-only verifier независимо сверил JSON, документацию, 68/68 post-verdict mapping, счётчики, времена и память; научных расхождений не найдено.

Следующий этап

Сначала анализируется честный offline FAIL. Порог этого independent pass не менять задним числом и второй улучшенный pass автоматически не запускать. Повторный RF TX, gain ladder, JPEG, video, QPSK, erasure FEC и ARQ без новой отдельной постановки запрещены.

Запись 031

Дата

2 сентября 2026 года

Тема

Lab046C: независимая повторная обработка короткой записи 1400 МГц с отдельным статистическим допуском кандидатов, без нового RF.

Выполнено

Использована сохранённая запись 20260901_172749_1400MHz/rx_1400mhz.cs8: 19 200 000 комплексных отсчётов cs8, 2,4 с при 8 МГц, SHA-256 06ab0867865bca462a21c42c9f3bc7e519e336108f7b5e98e7b283f842387a99. HackRF не запускался, RF TX = 0. Исторический порог IQ_PREAMBLE_THRESHOLD = 0.65, Lab045, FEC и PHY не изменялись. Исходный аппаратный CONTROL RESULT = C сохранён без переписывания.

До полного независимого декодирования зафиксировано отдельное правило первого каскада только по фону до передачи 0,00 ... 0,50 с: pre-TX local-peak Q99.9 + 4 * local-peak MAD. Q99.9 равен 0.022788675501942635, MAD равен 0.0027075146790593863, итоговый порог равен 0.03361873421818018. На независимом контрольном фоне после передачи 1,60 ... 2,40 с максимум равен 0.02711654081940651, кандидатов 0. Порог после просмотра результата не менялся.

Перед полным проходом независимая проверка выявила небезопасную при отказе ошибку общей точки приёма: противоречивый результат accepted=True, CRC_FAIL мог увеличить VALID_FRAMES. Добавлена обязательная повторная проверка CRC PASS; сценарий после исправления даёт VALID_FRAMES = 0. Независимая повторная проверка признала исправление чистым.

Выполнен ровно один полный проход всей записи без смещений TX, ожидаемого числа кадров, сигнала TX, пакетов, полезной нагрузки и кодированных битов. Получено 29 205 локальных максимумов и 1 279 кандидатов первого каскада. Строгий каскад обработал 28 кандидатов: PHY-заголовок PASS/FAIL 3/25, FEC attempts/PASS/FAIL 3/3/0, CRC PASS/FAIL 3/0, VALID FRAMES = 3. Поиск завершился по концу записи и списка кандидатов; ограничения безопасности не сработали.

Независимый результат записан до открытия опорных данных передатчика. Только после этого три действительных кадра сопоставлены с тремя переданными: пропущено 0, FALSE CRC PASS = 0, ошибки положения 0/-1/+2 отсчёта. Ошибки до FEC составили 17 + 19 + 29 = 65 бит, после FEC 0 бит, в полезной нагрузке 0 байт и 0 бит. Независимая проверка готовых JSON и трёх пар полезной нагрузки/пакета расхождений не выявила. 1400 MHz OFFLINE REPROCESSING = PASS, RF PATH ASSESSMENT = HEALTHY.

Итоговый программный шлюз перед полным проходом: python tools/quick_gate.py код 0 и 512 проверок; python -m pytest tests/ -q = 512 passed; git diff --check код 0 с информационными уведомлениями LF/CRLF. Git add, commit и push не выполнялись.

Подробный отчёт и машинно-читаемые результаты сохранены в docs/lab046c_1400mhz_offline_reprocessing.md и data/processed/lab046c_1400mhz_offline/.

Следующий этап

STOP. Новый RF, повтор Lab046C, изменение порога, JPEG, QPSK и изменение FEC без отдельной постановки запрещены.

Запись 032

Дата

2 сентября 2026 года

Тема

Lab046C: успешная полная передача объекта 16384 байта через аппаратный радиоканал 1400 МГц, RESULT A.

Выполнено

После отдельной точной авторизации выполнен один непрерывный процесс передачи без повтора. Новый криптографически случайный объект 16384 байта разбит существующей архитектурой Lab046 на 68 фрагментов и передан 68 последовательными защищёнными BPSK-кадрами. RF равна 1400 МГц, частота дискретизации 8 МГц, символьная скорость 20 ксимв/с, цифровое смещение несущей +50 кГц. Усиления сохранены: TX VGA 10 дБ, RX LNA/VGA 24/24 дБ, RF amplifier и Bias-Tee выключены. MASTER reg29 0x26, SLAVE CLKIN DETECTED, SLAVE reg29 0x26; общий опорный генератор прошёл проверку.

Поток передачи содержит 156 835 200 комплексных отсчётов, 313 670 400 байт и 19,6044 с сигнала. Приём содержит 192 000 000 комплексных отсчётов, 384 000 000 байт и 24,0 с сигнала. Приём начался на 0,7525116 с раньше передачи и закончился на 3,6341200 с позже. RX overruns 0, TX underruns 0, clipping 0, near limit 0. После опыта оба CLKOUT выключены, оставшихся процессов hackrf_transfer нет.

До полного декодирования по фону до передачи зафиксирован порог первого каскада Q99.9 + 4 * MAD: Q99.9 0.023181289434432983, MAD 0.0025865877978503704, threshold 0.033527640625834465. На независимом фоне после передачи maximum 0.030997175723314285, кандидатов 0. Порог после начала декодирования не менялся. Исторический строгий IQ_PREAMBLE_THRESHOLD = 0.65, Lab045, PHY и FEC не менялись.

Независимый приёмник обработал весь 24-секундный файл без смещений и периода кадров передатчика, ожидаемого числа 68, пакетов, кодированных битов и исходного объекта. Получено 295469 локальных максимумов, 35009 кандидатов первого каскада и 95 обработанных неперекрывающихся гипотез. PHY-заголовок PASS/FAIL 68/27, FEC attempts/PASS/FAIL 68/68/0, CRC PASS/FAIL 68/0, действительных кадров 68. Поиск завершился по концу записи и списка кандидатов, а не по известному количеству кадров.

До открытия опорных данных передатчика ObjectAssembler независимо принял 68 уникальных фрагментов без дубликатов, конфликтов и пропусков: OBJECT COMPLETE = YES. Только после фиксации этого вердикта выполнено сравнение с передатчиком. Совпали 68/68 кадров, пропущено 0, ложных CRC PASS 0. До FEC обнаружено 787 ошибок кодированных бит, после FEC 0 ошибок протокольных бит. Восстановленный объект имеет 16384 байта, 0 ошибочных байт и 0 ошибочных бит. SHA-256 исходного и восстановленного объектов совпадает: b5a27caaa3f03dfc468e71a857a06f18cf0259ca6ea21d3c42ccfde7168d1dfe.

SNR min/median/max для 68 кадров равен 8.302870/8.909278/9.837726 дБ, ошибки преамбулы 0/3/9 из 1280, CFO -0.214661/0.016493/0.281551 Гц. Медианный SNR по третям сеанса снижался 9.29 -> 8.86 -> 8.57 дБ, но потерь кадров и CRC FAIL не было. Итог: LAB046C HARDWARE RESULT = A; FULL RF OBJECT TRANSPORT = PASS; 68/68 FRAMES; OBJECT COMPLETE = YES; SHA MATCH = YES; OBJECT BYTE ERRORS = 0.

Большие сформированные артефакты оставлены вне Git в C:\Users\user\Documents\SDR_Rover_Lab046_raw\20260902_151819_1400MHz_full. Независимый проверяющий только чтением сверил аппаратные и независимые JSON, арифметику порога, счётчики, размеры, SHA-256, побайтовое совпадение объектов, временное покрытие RX над TX и очистку; расхождений не найдено. После опыта python tools/quick_gate.py прошёл, python -m pytest tests/ -q дал 512 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 не запускать.

Запись 035

Дата

3 сентября 2026 года

Тема

Lab048: профилирование и ускорение автономного приёмника Lab047 до обработки быстрее реального времени.

Выполнено

Работа выполнена только на сохранённой аппаратной RX-записи Lab047 C:\Users\user\Documents\SDR_Rover_Lab047_raw\20260903_115747\rx_stream.cs8: 120000000 комплексных отсчётов, 240000000 байт, 15,0 с, SHA-256 8521bf1b574cd1fe4e0a4f980c00c8664f8bb51551a241e46449e1eb2c77e635. Новый RF не выполнялся, RF TX = 0, HackRF не запускался.

Исходная контрольная точка: полное время 37,423910 с, строгая ступень 32,459969 с, в среднем 0,470434 с на один из 69 строгих кандидатов, приблизительный пик памяти 1545755352 байта, около 1,44 ГиБ. Результат Lab047: 36/36 кадров, CRC PASS/FAIL 36/0, полный JPEG, точный SHA-256, 0 ошибочных байтов и битов.

До изменения кода выполнен один полный проход под cProfile. Профилировщик увеличил время до 45,947287 с, но сохранил 185828 локальных максимумов, 32414 кандидатов первого каскада, 69 строгих проверок, 36 действительных кадров и точный JPEG. Основные затраты: decode_candidate_from_memmap 40,912 с, _extract_soft_window 25,697 с, _matched_waveform 21,199 с, fftconvolve 13,660 с, формирование RRC-коэффициентов 11,885 с и временная синхронизация 4,140 с. Опорная преамбула формировалась 70 раз, RRC-коэффициенты — 175 раз. Витерби занял только 0,875 с на 36 кадров, CFO/фаза 0,054 с, PHY-заголовок 0,006 с; эти части не оптимизировались.

Реализованы ограниченные вычислительные оптимизации без изменения научных критериев: кэшированы неизменяемые опорная PRBS7-преамбула и RRC-коэффициенты; полная линейная RRC-свёртка переведена с fftconvolve на математически эквивалентный overlap-add; кэшированы не более четырёх векторов переноса несущей; рабочие массивы согласованного фильтра переведены с complex128 на complex64, коэффициенты — на float32; те же 1601 преамбульные оценки timing считаются группами по 400 фазам без второго одинакового набора оценок.

Прямое сравнение старого и нового согласованного фильтра ограничивает абсолютное расхождение величиной 2e-6 и относительное к пику величиной 5e-7. Максимальное измеренное абсолютное расхождение равно 1,263e-6. Отдельные тесты подтверждают точность и неизменяемость кэшей, ограниченный размер кэша, тот же timing offset и отсутствие TX/expected-frame параметров у независимого API. Связанные тесты дали 169 passed.

После программного шлюза выполнен один итоговый полный проход той же записи. Первый вызов нового командного файла остановился до импорта проекта из-за отсутствующего загрузочного пути; RX не открывался и файл-свидетель не был создан. После исправления загрузочного блока выполнен ровно один фактический полный проход без автоматического повтора.

Итоговое время равно 13,966058 с: грубый поиск 4,776677 с, строгая ступень 9,171629 с, средняя строгая проверка 0,132922 с. Ускорение полного прохода 2,679633 раза, отношение времени обработки к 15,0 с эфира 0,931071: REAL-TIME CAPABLE = YES. Сохранены все исходные счётчики: 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.

Независимый приёмник не получал ожидаемого числа кадров, TX offsets, номеров TX-фрагментов, переданного JPEG, пакетов или кодированных битов. Только после завершённого независимого вердикта подтверждены 36/36 переданных кадров, 19 ошибок кодированных бит до FEC, 0 ошибок после FEC и 0 ложных CRC PASS. Восстановленный JPEG имеет 8724 байта, RGB 320 x 240, декодируется Pillow и имеет тот же SHA-256 e913dab9ac32795250880a4be67fbbbf89a4f96536842476ab591d1acaafc02a; ошибочных байтов 0, ошибочных битов 0.

После оптимизации крупнейшее верхнеуровневое узкое место — грубый поиск, 4,776677 с. В строгой ступени согласованный фильтр занимает 3,282575 с, уточнение начала 3,121533 с, timing 1,270783 с, Витерби 0,627109 с. Пиковая оценка памяти осталась около 1,44 ГиБ, потому что её определяет неизменённый 16-миллионный блок грубого поиска; уменьшение блока не выполнялось, чтобы не изменять границы и результат детектора.

Созданы experiments/lab048_receiver_performance.py, tests/test_lab048_receiver_performance.py, docs/lab048_current_state.md и малые артефакты в data/processed/lab048. Изменены только вычислительные примитивы в experiments/lab043_hackrf_bpsk.py, experiments/lab044_hackrf_bpsk_packet.py и experiments/lab046b_continuous_iq.py, а также этот журнал и указатель лабораторных. До итогового прохода python tools/quick_gate.py прошёл с 547 тестами и 11 функциональными проверками; python -m pytest tests/ -q дал 547 passed и 0 failed; git diff --check прошёл.

Следующий этап

STOP. Не переходить к Lab049, видео, QPSK, повышению символьной скорости или новому RF-сеансу без отдельной постановки. RF TX = 0; HackRF не запускать.