Files
SDR-Rover/PROJECT_LOG.md
2026-09-01 17:09:27 +03:00

962 lines
87 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Инженерный журнал 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 без новой
отдельной постановки запрещены.