# Lab049: отдельный ELRS для управления и SDR для видео Актуальная архитектурная постановка от 8 сентября 2026 года: **RadioMaster → штатный ELRS → CRSF → контроллер ровера** для управления и критической телеметрии; отдельный SDR — для изображений и объёмных данных. Будущие примерно 180 МГц относятся только к SDR; аппаратная лабораторная база остаётся 1400 МГц. Стандартный ELRS не объявляется работающим на 180 МГц. Подробный [аудит CRSF/ELRS, схема и контракт безопасности](lab049_crsf_elrs_architecture.md) сверен с официальным ExpressLRS 4.1.0. Модели аппаратуры пока не указаны, сопряжение контроллера с CRSF и сквозная безопасность не реализованы/не проверены. Сохраняются локальное торможение при потере управления, аварийная защёлка, защита от самовозобновления. Видео не обновляет таймер управления. Прежний общий CONTROL > TELEMETRY > VIDEO — исторический стресс-тест ниже. Его 20 CONTROL и 10 TELEMETRY в секунду **не резервируют ёмкость SDR**. Старые программные результаты и отрицательные вердикты сохранены. | SDR, ксимв/с | JPEG 8724 байта в идеале, кадры/с | Полезно, кбит/с | |---|---:|---:| | 20 | 0,09635 | 6,724 | | 50 | 0,24088 | 16,811 | | 100 | 0,48175 | 33,622 | | 200 | 0,96350 | 67,245 | Требуется **больше 3 кадров/с**: 3 — промежуточный минимум, 5 — следующий ориентир, 10 — дальнейший. Тот же JPEG в нынешнем PHY требует соответственно 622,728 / 1037,880 / 2075,760 ксимв/с с защитными интервалами, без запаса на потери и объёмные данные. Только JPEG: 209,376 / 348,960 / 697,920 кбит/с. Штатная ELRS-телеметрия для такого видео недостаточна; официальные источники, расходы по ступеням, движение и бюджет полной задержки приведены в новом отчёте. Новый [расчётчик](../experiments/lab049_crsf_elrs_budget.py) создаёт отдельный [crsf_elrs_budget.json](../data/processed/lab049/crsf_elrs_budget.json), переиспользует существующие независимые замеры IQ по SHA и не запускает RF. Он считает ELRS-возможности слотов, не измеренную задержку стики→ровер. 35 новых тестов бюджета проходят; quick_gate: 606 тестов и 13 функциональных проверок, полный pytest: 606 passed, git diff --check: PASS. Одно предупреждение pytest относится к доступу к `.pytest_cache`; ruff не установлен. Независимые verifier/adversary не обнаружили воспроизведённых расхождений. Подробности общих проверок — в записи 038. Следующий рекомендуемый Lab050: программное профилирование и потоковая обработка SDR-видео с ограничением возраста очереди; затем отдельное сопряжение CRSF. ## Сохранённый независимый IQ-опыт и общий стресс-тест Актуальный программный результат от 8 сентября 2026 года: **полностью пригодного режима нет**. Максимальная проверенная скорость с точным JPEG в идеальном и фиксированном шумном сценариях — 200 ксимв/с. Полный приёмник в шумном сценарии не успевает в реальном времени ни в одном режиме. Это результат одного воспроизводимого сценария, не универсальная оценка предела устойчивости BPSK. Для отдельного будущего диагностического PHY-опыта выбран **50 ксимв/с, 160 выборок/символ**: точный JPEG, полезная скорость в 2,5 раза выше базовой и наименьшая вычислительная перегрузка среди точных шумных проходов (1,3543). Он не готов к непрерывному объединённому каналу: блокировка 115,32 мс, перегрузка служебным трафиком и нарушенный аварийный срок. Это кандидат для диагностики, не разрешение RF. 100 ксимв/с лучше по блокировке, но требует 3,60 длительности IQ для обработки; 200 ксимв/с — 7,32. ## Аудит и исправления При входе в задачу Lab049 уже существовала без коммита. Старый результат сохранён как `data/processed/lab049/frame_aligned_result.json`; запись 036 журнала не переписана. Они измеряли заранее выровненные кадры без остаточного CFO. Новые данные — `data/processed/lab049/result.json` и идентичный `independent/result.json`. [Аудит](lab049_audit.md) содержит карту функций, проверку Lab033–Lab041 и воспроизведённые отказы. Основной RX получает целый IQ-поток без TX-границ, payload, объекта или ожидаемого числа кадров. Используются блочный поиск и строгий декодер Lab048: `lab046c_offline_recovery.stream_process_capture`. Сохранён порог Lab047 `0.030964473262429237`. Адаптер последовательно задаёт Rs/SPS и предоставляет чтение синтетического complex64; исходные константы и функции возвращаются через finally. Старый локальный `receive_iq_frame` остаётся для регрессий формы, основной проход его не использует. Fs = 8 000 000 выборок/с. Отношения Fs/Rs точные, дробные входы и нецелое samples/symbol отвергаются. BPSK, PRBS7, PHY header, packet/fragment, CRC, свёрточный FEC R=1/2 K=7 (171/133 octal), tail bits и перемежитель сохранены. Новый планировщик не создан, protocol не изменён. ## Канал и объект Один JPEG Lab047: 8724 байта, RGB 320×240, SHA-256 `e913dab9ac32795250880a4be67fbbbf89a4f96536842476ab591d1acaafc02a`; без перекодирования. Каждый проход: JPEG → фрагменты → protocol packets → FEC → interleaver → BPSK/RRC → CS8-квантование → IQ → независимый поиск → CFO/фаза/полярность → PHY/FEC/CRC → сборка → JPEG decode. Идеальный канал не добавляет шум/CFO. Шумный: единый coded-bit Eb/N0=7 dB, seed=49000+номер кадра, остаточный CFO +10 Гц, фаза 0,73 рад и чередование полярности. Eb = sum(abs(IQ)**2)/число символов; sigma² каждой компоненты шума = Eb/(2×10**(7/10)). Нормировка одинакова во всех режимах, параметры не подбирались до PASS. Ведущий, межкадровые и конечный интервалы не кратны символу; фон имеет отдельные фиксированные seeds. После добавления шума IQ не переквантован в CS8, чтобы не отсекать шум. Кадр занимает 5766 символьных интервалов с фильтром и защитными интервалами; JPEG — 36 кадров. Длительность IQ включает ещё 0,079217625 с фона. Полезная скорость считается по чистому времени JPEG, отношение обработки — по всей длительности IQ. Измеряются поиск, декодирование, сборка и JPEG decode; генерация канала и TX-сравнение после вердикта исключены. Все восемь проходов завершились END_OF_STREAM. Первый пробный прогон с лимитами Lab046B 32/256 был неполным; итоговые результаты получены после перехода на полный блочный путь с независимыми лимитами 4096/100000. ## Результаты IQ | Метрика | 20 ксимв/с | 50 ксимв/с | 100 ксимв/с | 200 ксимв/с | |---|---:|---:|---:|---:| | Выборок/символ | 400 | 160 | 80 | 40 | | Кадр, мс | 288.300 | 115.320 | 57.660 | 28.830 | | Кадров JPEG | 36 | 36 | 36 | 36 | | JPEG airtime, с | 10.37880 | 4.15152 | 2.07576 | 1.03788 | | Полезно, байт/с, идеал | 840.560 | 2101.399 | 4202.798 | 8405.596 | | Полезно, кбит/с, идеал | 6.724 | 16.811 | 33.622 | 67.245 | | Идеал: кадры / SHA | 36/36 / да | 36/36 / да | 36/36 / да | 36/36 / да | | Шум: кадры | 6/36 | 36/36 | 36/36 | 36/36 | | До FEC, принятые кадры | 67 | 147 | 119 | 125 | | После FEC, принятые кадры | 0 | 0 | 0 | 0 | | CRC PASS / FAIL | 6 / 0 | 36 / 0 | 36 / 0 | 36 / 0 | | Шум: JPEG SHA / decode | нет / нет | да / да | да / да | да / да | | Ошибки JPEG байт / бит | не восстановлен | 0 / 0 | 0 / 0 | 0 / 0 | | Обработка идеала, с | 8.73746 | 5.69848 | 7.36877 | 6.45915 | | Обработка шума, с | 173.65057 | 5.72980 | 7.76244 | 8.17573 | | Длительность IQ, с | 10.458018 | 4.230738 | 2.154978 | 1.117098 | | Обработка / IQ, шум | 16.604540 | 1.354327 | 3.602096 | 7.318724 | | Реальное время, шум | нет | нет | нет | нет | | Статус | FAIL | PARTIAL | PARTIAL | PARTIAL | На 20 ксимв/с 67 ошибок до FEC и 0 после относятся **только к шести принятым кадрам**. JPEG не восстановлен; полезная скорость целых JPEG в шумном проходе равна нулю. Остальные 30 кадров нельзя объявлять безошибочными. Проверено 2378 кандидатов, 2372 отклонены на PHY header. На 50/100/200 проверено 59/237/474 кандидата. Кандидат, не достигший CRC, не записан как CRC FAIL. Причины сохранены в JSON. Порог и шум после отказов не менялись. Все идеальные проходы имеют ноль ошибок до/после FEC. Базовые 6,724 кбит/с согласуются с примерно 6,7 кбит/с Lab047. Выигрыш 2,5/5/10 рассчитан по фактической форме и числу кадров, а не обещан заранее. Исторические аппаратные результаты Lab047/Lab048 не опровергнуты: здесь другой канал. ## Планирование и задержки Переиспользован LATEST_STATE: EMERGENCY > CONTROL > TELEMETRY > VIDEO. Проверка даёт VIDEO(active) → EMERGENCY → CONTROL → TELEMETRY → VIDEO. Физический кадр не прерывается, но весь JPEG не удерживает канал. CONTROL — штатные 36 байт, 20 Гц (Lab041); TELEMETRY — синтетические 64 байта, 10 Гц (Lab037–Lab041); EMERGENCY — штатный EmergencyStop, 34 байта, t=0,777 с. Служебная нагрузка генерируется 2 с. Запас VIDEO 256 пакетов не исчерпывается в этом окне. Каждый пакет модели занимает один полный PHY-кадр. Это модель занятости; упаковка LinkPacket в аппаратный 256-байтный PHY payload не реализована. Прикладные CONTROL/EMERGENCY сохраняют точные сериализованные байты. Задержки не включают программное время RX, потери, повторы и привод; это не гарантия времени физического торможения. Блокировка — остаток начатого VIDEO; доставка EMERGENCY в худшей фазе — почти два кадра, включая саму команду. Старое поле deadline в priority_probe сохранено как совместимое поле блокировки с явным scope; классификация использует новый delivery flag. | Метрика | 20 ксимв/с | 50 ксимв/с | 100 ксимв/с | 200 ксимв/с | |---|---:|---:|---:|---:| | CONTROL max VIDEO blocking, мс | 288.30 | 115.32 | 57.66 | 28.83 | | EMERGENCY max VIDEO blocking, мс | 288.30 | 115.32 | 57.66 | 28.83 | | EMERGENCY worst delivery, мс | 576.60 | 230.64 | 115.32 | 57.66 | | CONTROL blocking <100 / <50 мс | нет / нет | нет / нет | да / нет | да / да | | EMERGENCY delivery ≤50 мс | нет | нет | нет | нет | Доставка **в активном окне 0–2 с**, min / median / max, мс. Заменённые и ещё не доставленные состояния сюда не входят: | Метрика | 20 ксимв/с | 50 ксимв/с | 100 ксимв/с | 200 ксимв/с | |---|---:|---:|---:|---:| | CONTROL | 289.90 / 303.20 / 316.50 | 116.92 / 136.28 / 162.88 | 58.84 / 82.03 / 105.64 | 30.01 / 43.94 / 61.07 | | EMERGENCY | 376.20 / 376.20 / 376.20 | 145.56 / 145.56 / 145.56 | 87.90 / 87.90 / 87.90 | 30.24 / 30.24 / 30.24 | | TELEMETRY | нет доставленных | нет доставленных | нет доставленных | 33.84 / 45.54 / 89.69 | | VIDEO | 288.30 / 288.30 / 288.30 | 115.32 / 115.32 / 115.32 | 57.66 / 57.66 / 57.66 | 28.83 / 850.49 / 1845.12 | Доставка **до полного опустошения очереди**, отдельно от активной нагрузки: | Метрика | 20 ксимв/с | 50 ксимв/с | 100 ксимв/с | 200 ксимв/с | |---|---:|---:|---:|---:| | CONTROL, мс | 289.90 / 303.20 / 331.40 | 116.92 / 139.48 / 216.08 | 58.84 / 83.84 / 105.64 | 30.01 / 43.73 / 61.07 | | EMERGENCY, мс | 376.20 / 376.20 / 376.20 | 145.56 / 145.56 / 145.56 | 87.90 / 87.90 / 87.90 | 30.24 / 30.24 / 30.24 | | TELEMETRY, мс | 644.70 / 644.70 / 644.70 | 356.40 / 356.40 / 356.40 | 183.42 / 183.42 / 183.42 | 33.84 / 45.54 / 89.69 | | VIDEO, мс | 288.30 / 39352.95 / 76111.20 | 115.32 / 17009.70 / 31713.00 | 57.66 / 9485.07 / 16836.72 | 28.83 / 5434.46 / 9110.28 | | Конец опустошения, с | 76.11120 | 31.71300 | 16.83672 | 9.11028 | | Превышения CONTROL / EMERGENCY | 6 / 1 | 17 / 1 | 6 / 1 | 0 / 0 | Очередь заменяет старое ожидающее состояние, но не удаляет пакет по deadline. На 20/50/100 за активные 2 с доставлено 0 TELEMETRY. У 200 конкретная EMERGENCY доставлена за 30,24 мс, но худшая фаза 57,66 мс всё равно нарушает срок 50 мс. ## Исторический бюджет единого канала — не бюджет целевой архитектуры Прикладные CONTROL/TELEMETRY: 5760/5120 бит/с; вместе с LinkPacket до PHY — 10880/7680 бит/с. Физическая стоимость: 20/10 полных кадров/с, или **115320/57660 символьных интервалов в секунду** BPSK, включая всю форму. Эту стоимость нельзя прямо вычитать из JPEG-бит/с: остаток считается через время эфира. JSON-поля reserved_link_bps 46080/23040 относятся к внутренним 288-байтным представителям планировщика, а не к физическому кодированному потоку. | Метрика | 20 ксимв/с | 50 ксимв/с | 100 ксимв/с | 200 ксимв/с | |---|---:|---:|---:|---:| | CONTROL, запрошено % эфира | 576.60 | 230.64 | 115.32 | 57.66 | | TELEMETRY, запрошено % эфира | 288.30 | 115.32 | 57.66 | 28.83 | | EMERGENCY, событие/2с, % эфира | 14.415 | 5.766 | 2.883 | 1.442 | | VIDEO после C+T, кбит/с | 0.000 | 0.000 | 0.000 | 9.085 | | Теоретические JPEG/с после C+T | 0.00000 | 0.00000 | 0.00000 | 0.13017 | | VIDEO после C+T+E, кбит/с | 0.000 | 0.000 | 0.000 | 8.115 | Процент больше 100 означает перегрузку, а не фактически переданные данные. Только 200 оставляет VIDEO: 9,085 кбит/с и около 0,1302 JPEG/с; с одной EMERGENCY за 2 с — 8,116 кбит/с. Это потенциал модели, не видеопоток: вычислительная перегрузка и аварийный срок остаются. ## Проверки предыдущего IQ-этапа Независимые verifier/adversary воспроизвели прежние отказы и подтвердили исправления. Verifier: 24 целевых теста PASS, независимый пересчёт JSON совпал. Adversary: правильный отрицательный аварийный вердикт и отдельное активное окно. - python tools/quick_gate.py: PASS, 571 тест ядра, 12 функциональных проверок. - python -m pytest tests/ -q: 571 passed, 0 failed; одно предупреждение о запрете записи .pytest_cache. - git diff --check: PASS. RF TX = 0. HackRF не запускался. Git add/commit/push/pull/fetch не выполнялись. STOP. Следующий этап требует отдельной постановки: вычислительная перегрузка, бюджет и задержки перед аппаратным опытом. QPSK, новый FEC, реальное видео и переход на 180 МГц в этой работе не выполнялись.