Lab046A: validate continuous soft-symbol frame scanning
This commit is contained in:
@@ -2,7 +2,10 @@
|
||||
|
||||
## Статус
|
||||
|
||||
**SOFTWARE VALIDATED. RF TX = 0.
|
||||
**LAB046 SOFTWARE OBJECT TRANSPORT = COMPLETE.**
|
||||
|
||||
**CONTINUOUS STREAM VALIDATION = PASS (NORMALIZED SOFT-SYMBOL LEVEL). RF TX = 0.
|
||||
CONTINUOUS SAMPLE/IQ VALIDATION = NOT PERFORMED.
|
||||
HARDWARE VALIDATION = NOT PERFORMED.**
|
||||
|
||||
Lab046 — только программная лаба. HackRF и `hackrf_transfer` не
|
||||
@@ -46,6 +49,77 @@ fragment_count u16, original_size u32).
|
||||
использован и НЕ изменён — он остаётся будущим расширением для потери целых
|
||||
фрагментов, а не для битовых ошибок (это работа свёрточного кода).
|
||||
|
||||
После этого Lab046A закрыла оставшийся пробел: до неё Lab046 передавала каждый
|
||||
кадр отдельным вызовом и выбирала его из TX-плана по известному индексу. Функции
|
||||
поиска нескольких кадров в одном потоке не было. Теперь
|
||||
`scan_continuous_soft_stream` получает только один массив soft-символов,
|
||||
самостоятельно ищет PRBS7 после монотонного cursor, проверяет защищённый PHY
|
||||
header, вычисляет длину coded body из принятого packet length, выполняет готовые
|
||||
FEC/CRC Lab045 и передаёт принятый fragment в `ObjectAssembler`.
|
||||
|
||||
TX offsets, список длин кадров, ожидаемое число 68, порядок/индексы TX,
|
||||
исходный объект, TX packets и coded bits scanner-у не передаются. TX-side
|
||||
`frame_starts` остаётся только в генераторе потока и используется тестом для
|
||||
сравнения уже после независимого receive.
|
||||
|
||||
## Граница доказательства Lab046A
|
||||
|
||||
Lab046A работает на уровне **одного непрерывного нормализованного soft BPSK
|
||||
stream** (`float32`). Это разрешённый интерфейс после уже проверенного в Lab045
|
||||
sample-level front-end: PRBS7 detection, matched filtering, timing, CFO и
|
||||
phase/polarity recovery. Внутри нового длинного теста эти sample-level операции
|
||||
заново не моделируются для каждого кадра. Поэтому результат доказывает
|
||||
самостоятельный поиск границ, header-driven длину, FEC/CRC и сборку объекта в
|
||||
непрерывном soft stream, но не является аппаратной или непрерывной IQ-проверкой.
|
||||
|
||||
Каждый фрагмент содержит полный активный Lab045 PHY frame: 1280 бит PRBS7,
|
||||
144 бита защищённого header и 4300 coded bits. Точная полная sample-level форма
|
||||
с guard и хвостом ФРК учитывается как 2 306 400 отсчётов на кадр, однако все
|
||||
156 835 200 IQ-отсчётов одновременно в памяти не создаются. Это намеренное
|
||||
ограничение памяти, а не использование известных границ приёмником.
|
||||
|
||||
Scanner fail-closed:
|
||||
|
||||
- cursor всегда растёт, после принятого кадра переносится за вычисленный конец;
|
||||
- все PRBS7 candidates выше порога рассматриваются в порядке stream; после
|
||||
принятого кадра cursor переносится за вычисленный конец и не даёт
|
||||
декодировать этот кадр повторно;
|
||||
- плохой header, усечённое body, ошибка FEC/CRC отвергают candidate, но поиск
|
||||
следующего продолжается;
|
||||
- `MAX_FRAMES` и `MAX_SEARCH_ITERATIONS` дают явную причину остановки, а не
|
||||
частичный объект, объявленный полным;
|
||||
- scan продолжается до конца capture и не останавливается на числе 68.
|
||||
|
||||
## Сценарии continuous stream
|
||||
|
||||
| Сценарий | Получено |
|
||||
|---|---|
|
||||
| Идеальный, кадры подряд | candidates 68, valid headers 68, FEC PASS 68, CRC PASS 68/68, fragments 68, complete=True, SHA совпал, 0 байт-ошибок |
|
||||
| Фон до/между/после | 37/37/43 soft-символа, valid frames 68, complete=True, SHA совпал |
|
||||
| Непрерывный AWGN, sigma=0.40, seed=46001 | frames 68, pre-FEC 1791, post-FEC 0, CRC 68/0, complete=True, SHA совпал |
|
||||
| Valid-looking preamble + bad protected header | candidates 71, rejected 3, последующие valid frames 68, complete=True, SHA совпал |
|
||||
|
||||
Фон между кадрами добавлен только после кадров 7, 23 и 51: 11, 19 и 7
|
||||
soft-символов, всего 37. В baseline дополнительного inter-frame gap нет.
|
||||
Отдельный тест с валидным header для 12-байтного packet и повреждённым body
|
||||
проверяет, что scanner берёт длину именно из принятого header, отвергает этот
|
||||
candidate и затем находит настоящий кадр.
|
||||
|
||||
Verifier нашёл опасный вариант прежнего глобального non-maximum suppression:
|
||||
более сильный ложный PRBS7 peak мог удалить более поздний настоящий старт
|
||||
кадра. Поэтому suppression убран из списка кандидатов, а добавленный
|
||||
регрессионный тест проверяет, что ложный peak не скрывает настоящий кадр.
|
||||
|
||||
## Память continuous stream
|
||||
|
||||
Основной 68-кадровый soft stream содержит 389 232 значения `float32` и занимает
|
||||
1 556 928 байт (1,485 MiB). Массив correlation scores занимает 1 551 812 байт,
|
||||
накопленная энергия `float64` — 3 113 864 байта. FFT и denominator создают
|
||||
временное рабочее пространство, размер которого зависит от SciPy, но стратегия
|
||||
остается в пределах десятков MiB, а не нескольких GiB. Для сравнения, один
|
||||
материализованный continuous `complex64` IQ stream из 156 835 200 отсчётов
|
||||
занял бы около 1,17 GiB ещё до временных копий.
|
||||
|
||||
## Детерминированный объект
|
||||
|
||||
- Размер **16384 байта (16 KiB)**. Это не JPEG, а воспроизводимый
|
||||
@@ -118,8 +192,12 @@ count/original_size, невозможный индекс, конфликтующ
|
||||
| Число BPSK-кадров | 68 |
|
||||
| Всего информационных BPSK-символов | 389 232 (5724 × 68) |
|
||||
| Всего отсчётов формы сигнала | 156 835 200 (2 306 400 × 68) |
|
||||
| Оценка эфирного времени | 19,60 с |
|
||||
| Полезный goodput | 835,7 байт/с = 6,69 кбит/с |
|
||||
| Baseline: дополнительный inter-frame gap | 0 отсчётов |
|
||||
| Baseline: полная длительность | 19,604400 с |
|
||||
| Baseline: полезный goodput | 835,7 байт/с = 6,685846 кбит/с |
|
||||
| Фоновый тест: leading/inter-frame/trailing | 14 800 / 14 800 / 17 200 отсчётов |
|
||||
| Фоновый тест: полная длина и длительность | 156 882 000 отсчётов, 19,610250 с |
|
||||
| Фоновый тест: фактический goodput | 6,683852 кбит/с |
|
||||
| Полезных бит на символ | ≈ 0,337 |
|
||||
|
||||
Учёт кадра совпадает с Lab045: 2144 информационных бита, 6 tail-бит, 4300
|
||||
@@ -149,15 +227,17 @@ Goodput 6,69 кбит/с — это честная baseline при 20 ксимв
|
||||
проходят (фрагмент туда-обратно, короткий последний фрагмент, чужой
|
||||
object_id, невозможный индекс, несогласованный счётчик, усечённые и абсурдные
|
||||
метаданные без крупной аллокации, полный тракт PHY для сценариев A–F,
|
||||
отсутствие оракула, детерминизм и SHA объекта).
|
||||
отсутствие оракула, последовательный continuous scan, rejected candidate,
|
||||
MAX_FRAMES/MAX_SEARCH_ITERATIONS, регрессия против удаления настоящего кадра
|
||||
ложным PRBS7 peak, детерминизм и SHA объекта).
|
||||
- Полный тракт `объект → фрагменты → кадр Lab045 → канал → приём → сборка`
|
||||
проверен для всех шести сценариев значениями выше.
|
||||
|
||||
## Software gate
|
||||
|
||||
- `python tools/quick_gate.py`: PASS; 438 тестов ядра, 6 функциональных
|
||||
- `python tools/quick_gate.py`: PASS; 454 теста ядра, 6 функциональных
|
||||
проверок лабораторий выполнено, 13 штатно пропущено.
|
||||
- `python -m pytest tests/ -q`: 438 passed, 0 failed, 0 errors, 0 skipped.
|
||||
- `python -m pytest tests/ -q`: 454 passed, 0 failed, 0 errors, 0 skipped.
|
||||
Единственное предупреждение связано с отсутствием прав на создание
|
||||
`.pytest_cache`; на выполнение и результат тестов оно не повлияло.
|
||||
- `git diff --check`: чист.
|
||||
|
||||
Reference in New Issue
Block a user