# Инженерный журнал SDR Rover Link ## Назначение журнала Этот файл содержит хронологию разработки проекта SDR Rover Link. В журнале фиксируются: - выполненные работы; - полученные результаты; - обнаруженные ошибки; - принятые технические решения; - результаты экспериментов; - планы следующего этапа. Записи не следует удалять. Если решение изменилось, необходимо добавить новую запись и объяснить причину изменения. --- # Запись 001 ## Дата 10 июля 2026 года ## Тема Создание структуры проекта и локального Git-репозитория. ## Выполнено 1. Проверена установленная версия Git: ```text 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 без отдельной постановки не начинать.