Files
SDR-Rover/docs/rf/RF_001_PLAN.md
2026-09-17 15:05:44 +03:00

13 KiB
Raw Blame History

RF-001 — подготовка первого QPSK-пакетного опыта

Статус: PREPARED / NOT_RUN. Это программная подготовка после коммита VIDEO-005 6df5f8a. SDR не открывался; приёма и передачи через него не было. RF TX = 0. Первый аппаратный сеанс требует отдельной постановки и прямого разрешения.

Цель и граница

Будущий опыт проверит известные PHY-пакеты через два Auron HackRF Plus. Утверждён один начальный режим: QPSK, 500 000 символов/с, внутренний FEC 2/3, прикладная нагрузка 256 байт, пауза 5 мс, 100 пакетов с номерами 0–99 и seed 20260917. H.264, камера, видеотранспорт, внешний erasure FEC и адаптивное переключение не участвуют. До первого аппаратного результата нагрузку не увеличивать, а паузу не уменьшать.

TX: payload(seed, sequence) → build_frame(QPSK, 2/3) → shape_packet(RRC)
    → IQ-файл → [будущий аппаратный IQSink]
RX: [будущий аппаратный IQSource] → исходный raw IQ-файл
    → receive_iq_stream() VIDEO-005 → CRC-valid пакеты
    → отдельное сравнение с TX-ведомостью и отчёт

PHY-приёмник не получает TX-границы, payload, истинную фазу, CFO, момент выборки или ожидаемое число пакетов. SHA и ошибки сравниваются после строгого декодирования. receive_iq_stream() для RF-001 не менялся. Исторический build_frame() ставит в пакет тип 3; здесь содержимое — тестовые байты, видеосборщик не вызывается.

Файловые инструменты

tools/qpsk_rf_tx.py создаёт весь IQ без аппаратных импортов в новом каталоге data/raw/rf001/offline_qpsk_100_packets/. Существующие файлы он не перезаписывает. Нагрузка каждого номера получается из SHA-256 по seed, номеру и счётчику блока, без зависимости от версии генератора NumPy.

python -B -X utf8 tools/qpsk_rf_tx.py

tx_waveform.c64le — сырые little-endian complex64, 8 байт на комплексный отсчёт, без заголовка. tx_metadata.json содержит test_id, UTC-время, режим, номинальный цифровой сдвиг несущей 125 кГц, seed, номера и SHA-256 payload/пакетов, паузу, dtype, число/длительность отсчётов, SHA IQ и TX-границы. Последние остаются только в ведомости. Форма каждого пакета включает по 64 защитных отсчёта на концах; между массивами вставлены 39 872 нулевых отсчёта. Итого пауза вместе с защитными участками — ровно 40 000 отсчётов = 5 мс. Это цифровая форма без аппаратной калибровки амплитуды и преобразования к формату TX устройства.

tools/qpsk_rf_rx.py читает c64le и вызывает существующий приёмник VIDEO-005. Необязательная TX-ведомость читается после вызова приёмника. Для будущего сохранённого аппаратного файла предусмотрен вход --iq-format cs8: чередующиеся знаковые байты I/Q преобразуются в complex64 для анализа, исходный файл не меняется; отдельно считаются коды насыщения −128/127. Это файловый конвертер, не аппаратный адаптер.

python -B -X utf8 tools/qpsk_rf_rx.py `
  --iq-file data/raw/rf001/offline_qpsk_100_packets/tx_waveform.c64le `
  --truth-metadata data/raw/rf001/offline_qpsk_100_packets/tx_metadata.json `
  --report data/processed/rf001/offline_roundtrip.json `
  --numba-packages C:\Users\user\Desktop\projects\SDR_Rover\.lab053_cpu_runtime\packages

Путь --numba-packages относится к текущему ПК; на втором ноутбуке Numba берётся из его окружения. Без TX-ведомости инструмент сообщает кандидатов преамбулы и CRC-пакеты, номера, повторы и оценки CFO/фазы/такта, но не объявляет точность или потери относительно неизвестного ожидаемого списка.

Программный круг на 100 пакетах

Показатель Результат
IQ 8 833 828 отсчётов; 1,1042285 с; 70 670 624 байта
SHA-256 IQ 7cd81395efaa88b623b7e4e5a02e3a80b52185007397ea56ceaacc13353974b2
Кандидаты корреляционного поиска / отвергнутые 557 / 457
CRC-valid / точные пакеты 100 / 100
Пропущенные / дубли 0 / 0
Raw BER по всем 100 принятым пакетам 0 / 322 500 кодированных битов
Ошибки после FEC 0 в сопоставленных пакетах

557 — кандидаты корреляции, а не 557 принятых преамбул. Только 100 прошли PHY/FEC/CRC. Raw BER получен отдельным повтором штатных PHY-функций после первого приёма. При потере пакетов полный raw BER неизвестен: API VIDEO-005 не отдаёт мягкие решения отвергнутых кандидатов. Тогда отчёт покажет BER на CRC-valid пакетах отдельно, а raw_ber оставит null. Условный BER нельзя выдавать за BER всего канала. Полный машинный отчёт сохранён в data/processed/rf001/offline_roundtrip.json; исходный IQ и TX-ведомость лежат в игнорируемом Git data/raw/rf001/.

Будущий захват и аппаратная граница

Следующий этап сначала сохраняет исходные байты аппаратного RX, затем анализирует их офлайн. Небольшая граница IQSource создаёт raw IQ-файл и capture_metadata.json; файловый анализатор читает сохранённый файл. IQSink сможет принять заранее проверенный TX-файл только после отдельного допуска. PHY-модули не знают о HackRF API; собственный libusb-слой не нужен.

Предлагаемый файловый контракт capture: capture.cs8 без заголовка, пары знаковых байтов I0,Q0,I1,Q1,…; исходный файл не нормализовать и не перезаписывать. capture_metadata.json создаётся рядом. Неизвестные поля остаются null или NOT_RUN, а не заполняются нулями:

{
  "schema_version": 1,
  "status": "NOT_RUN",
  "raw_iq_file": "capture.cs8",
  "iq_format": "cs8_interleaved_signed_iq",
  "sample_rate_hz": 8000000,
  "sample_count": null,
  "raw_iq_sha256": null,
  "capture_started_utc": null,
  "center_frequency_hz": null,
  "nominal_digital_carrier_offset_hz": 125000,
  "clock_mode": "NOT_RUN",
  "clock_link": "NOT_RUN",
  "estimated_sample_clock_offset_ppm": null,
  "cfo_series_hz": null,
  "timing_drift_series_symbols": null,
  "receiver_serial": null,
  "gain_settings": null,
  "common_clock": "NOT_RUN",
  "tx_underrun_observations": [],
  "rx_overrun_observations": [],
  "rx_clipping_rail_codes": null,
  "counter_observation_complete": false,
  "capture_validity": "NOT_RUN",
  "command_log": []
}

В metadata захвата потребуются время, путь/формат/SHA raw IQ, частота дискретизации, центр RF, номинальный цифровой сдвиг, число отсчётов, серийные номера, gain, состояние общей опоры, журнал команд и все наблюдения underrun/overrun/clipping по ходу сеанса. Неполный или нечистый счётчик делает результат непригодным для PASS; конечный ноль не отменяет промежуточную потерю. Сейчас аппаратного источника/стока и фактического capture metadata нет — это будущая отдельно разрешённая работа. Дрейф частоты дискретизации не моделировался в VIDEO-005 и остаётся отдельным риском для реального захвата.

RF-001 делится на два будущих режима с отдельным разрешением на каждый выход в эфир. RF-001A использует проводную общую опору 10 МГц только как лабораторный baseline: TCXO → MASTER → MASTER CLKOUT → SLAVE CLKIN. Предыдущие лабораторные проверки фиксировали MASTER и SLAVE reg29 = 0x26, SLAVE CLKIN = DETECTED. Это исторические данные, а не свежая проверка подключения. RF-001B использует независимые такты: провод CLKOUT → CLKIN снят. Именно этот вариант соответствует архитектуре ровера и НСУ без проводной опоры.

Для сравнения A/B одинаковыми остаются RF-частота, 500 ксимв/с, FEC 2/3, payload 256 байт, пауза 5 мс, 100 пакетов, TX-уровень, RX-усиления, геометрия, антенны и TX-волна. Оба сеанса сначала сохраняют исходный RX IQ и полный журнал счётчиков. В RF-001B по принятой преамбуле каждого пакета и известным TX-номерам нужно оценить CFO по времени и наклон ошибки момента выборки, затем разницу частот дискретизации. Эти оценки делаются после строгого PHY/FEC/CRC; потери и пропуски не подменяются известными границами передатчика. Программная сетка CLOCK-001 проверила до ±50 ppm, но фактический ppm плат ещё не измерен. Частота RF, gain, кабели, антенны и уровень сигнала для нового опыта не утверждены здесь; они войдут в отдельный аппаратный preflight.

Форма отчёта и следующий критерий

Будущий отчёт содержит RF-001 STATUS, режим, число кандидатов преамбулы, CRC-valid и точных пакетов, долю точных, raw BER с областью расчёта, ошибки после FEC, дубли/пропуски, медиану CFO и P95 |CFO|, оценки фазы/такта, TX underruns, RX overruns, RX clipping, общую опору DETECTED / NOT_DETECTED, SHA capture и причины отказа. Сейчас аппаратные поля — NOT_RUN, а не нули.

Для будущего короткого OTA smoke test, если захват и счётчики чисты: не менее 99 точных из 100 — GOOD; 95–98 — DIAGNOSTIC/PARTIAL; менее 95 — не переходить к видео. Это предварительная классификация, не эксплуатационная норма. Программные 100/100 не доказывают RF PASS.

Только после отдельного аппаратного PASS: сравнение пауз 5 → 2 → 1 → 0,5 → 0 мс при 256 байтах. После выбора паузы — отдельно 256 → 512 → максимально допустимый рабочий payload. Здесь матрица не выполняется.

RF-001 HARDWARE STATUS = NOT_RUN. SDR HARDWARE = NOT_ACCESSED. RF TX = 0. Следующий шаг — отдельное согласование preflight и одного контролируемого сеанса; автоматического перехода к эфиру нет.