522 lines
36 KiB
Markdown
522 lines
36 KiB
Markdown
# Lab043. Передача JPEG с Pluto+ на независимый RTL-SDR
|
||
|
||
## 1. Цель лабораторной
|
||
|
||
Передать тот же подготовленный JPEG, который использован в Lab042, с
|
||
Pluto+ на отдельный RTL-SDR и восстановить его побайтово.
|
||
|
||
В Lab042 передатчик и приёмник находились в одном Pluto+ и использовали
|
||
общий опорный генератор. Lab043 должна убрать это упрощение и раздельно
|
||
измерить три эффекта:
|
||
|
||
1. рассогласование несущих частот передатчика и приёмника;
|
||
2. относительное рассогласование частот дискретизации двух устройств;
|
||
3. начальную фазу выбора отсчёта символа внутри символьного интервала.
|
||
|
||
Лабораторная считается успешной только при выполнении радиокритериев,
|
||
прикладных критериев и программных проверок, определённых в разделе 11.
|
||
Запуск программы сам по себе успехом не считается.
|
||
|
||
## 2. Границы работы
|
||
|
||
Lab043 остаётся кабельной. Эфир добавил бы многолучёвость, внешние сигналы
|
||
и неконтролируемые потери, хотя предмет этой работы состоит в
|
||
синхронизации независимых устройств.
|
||
|
||
В Lab043 не входят:
|
||
|
||
- передача через антенны;
|
||
- выбор рабочего диапазона 200-250 МГц;
|
||
- ARQ и повторная передача;
|
||
- исправление стираний и новая FEC;
|
||
- потоковое видео;
|
||
- скачки по частоте;
|
||
- изменение логики управления и безопасности ровера.
|
||
|
||
Эфирный тракт остаётся предметом следующей лабораторной.
|
||
|
||
## 3. Подтверждённое оборудование и окружение
|
||
|
||
Состояние оборудования проверено непосредственным опросом. Перед
|
||
реализацией и перед каждым аппаратным прогоном его необходимо проверить
|
||
повторно.
|
||
|
||
### 3.1. Передатчик
|
||
|
||
- Pluto+;
|
||
- устройство должно открываться успешным `iio.Context`, а не проверяться
|
||
только командой `ping`;
|
||
- чип AD9361;
|
||
- используется первый передающий канал.
|
||
|
||
Конкретный рабочий URI IIO определяется повторным опросом перед опытом и
|
||
сохраняется в метаданных запуска. Исторически работали сетевой URI
|
||
`ip:192.168.2.1` и прямой USB IIO, но ни один из них нельзя считать
|
||
доступным без текущей проверки.
|
||
|
||
### 3.2. Приёмник
|
||
|
||
- USB ID `VID_0BDA&PID_2838`;
|
||
- имя библиотеки: `Generic RTL2832U OEM`;
|
||
- тюнер, сообщённый библиотекой: Fitipower FC0013;
|
||
- основной интерфейс `MI_00` использует WinUSB от libwdi;
|
||
- устройство открыто из Python через `pyrtlsdr` и `librtlsdr`;
|
||
- установка 435 МГц подтверждена чтением значения обратно;
|
||
- частота дискретизации 2 400 000 отсчётов/с работает;
|
||
- получены комплексные отсчёты;
|
||
- доступные аппаратные усиления находятся в диапазоне от -9,9 до
|
||
19,7 дБ и задаются дискретными ступенями устройства.
|
||
|
||
Ошибка второго USB-интерфейса не считается отказом SDR. Основной
|
||
интерфейс `MI_00`, через который работает `librtlsdr`, исправен.
|
||
|
||
### 3.3. Зафиксированное программное окружение
|
||
|
||
- Python 3.13.1 x64;
|
||
- `pyrtlsdr` 0.5.0;
|
||
- `pyrtlsdrlib` 0.0.5;
|
||
- поставляемая пакетом нативная `librtlsdr` v0.9.0;
|
||
- `pyadi-iio` и `pylibiio` для Pluto+.
|
||
|
||
Принятый способ доступа к RTL-SDR: API `pyrtlsdr` с поставляемой
|
||
`pyrtlsdrlib` нативной библиотекой. Малый собственный DLL-адаптер не
|
||
нужен. Реализация должна проверять версии и выдавать понятную ошибку, если
|
||
библиотека или устройство недоступны. Пользовательский путь к DLL
|
||
зашивать в код запрещено.
|
||
|
||
## 4. Физическая схема и безопасность
|
||
|
||
Схема:
|
||
|
||
`Pluto+ TX -> SMA-кабель -> AT30S 30 дБ -> переходник/кабель -> RTL-SDR RX`
|
||
|
||
Обязательные условия перед каждым включением TX:
|
||
|
||
1. Антенны Pluto+ и RTL-SDR сняты.
|
||
2. AT30S включён последовательно в тракт, а не подключён к свободному
|
||
порту.
|
||
3. Все разъёмы затянуты, кабель не отсоединяется при включённом TX.
|
||
4. Пользователь отдельно подтверждает эту физическую схему.
|
||
5. Первый заранее определённый рабочий режим: TX -30 дБ, RTL-SDR
|
||
19,7 дБ, несущая 435 МГц, номинально 2,4 Мвыб/с на обоих устройствах.
|
||
6. Автоматический перебор усилений, частот, порогов и способов
|
||
синхронизации запрещён.
|
||
7. Если первый режим не проходит, программа сохраняет исходные данные и
|
||
диагностику и останавливается. Следующий прогон разрешён только после
|
||
разбора причины и с изменением ровно одного заранее названного
|
||
параметра.
|
||
|
||
При TX -30 дБ расчётный уровень после AT30S составляет около -53 дБм.
|
||
Это значение следует из бюджета Lab042: около +7 дБм при TX 0 дБ,
|
||
минус 30 дБ настройки TX и минус 30 дБ аттенюатора. Расчёт не заменяет
|
||
проверку наличия аттенюатора и правильности схемы.
|
||
|
||
## 5. Номинальные параметры сигнала и обязательное чтение обратно
|
||
|
||
| Параметр | Запрошенное значение | Происхождение |
|
||
|---|---:|---|
|
||
| Несущая TX и RX | 435 МГц | Кабельная рабочая точка Lab042 |
|
||
| Символьная скорость | 20 000 симв/с | Lab018-Lab023 и Lab042 |
|
||
| Частота дискретизации TX | 2 400 000 отсчётов/с | Поддерживается Pluto+ и проверена на RTL-SDR |
|
||
| Частота дискретизации RX | 2 400 000 отсчётов/с | Проверена непосредственным опросом RTL-SDR |
|
||
| Номинальное число отсчётов на символ | 120 | 2 400 000 / 20 000 |
|
||
| Полоса TX | 200 кГц | Минимальная полоса AD9361, использованная в Lab042 |
|
||
| Размер данных фрагмента | 512 байт | Lab042 |
|
||
| Модуляция | BPSK | Lab018-Lab023 и Lab042 |
|
||
|
||
Одинаковое номинальное значение 2,4 Мвыб/с выбрано специально. Lab043
|
||
измеряет физическую ошибку генераторов, а не искусственно созданную
|
||
разницу номинальных частот дискретизации.
|
||
|
||
Перед аппаратным опытом программа обязана установить и прочитать обратно:
|
||
|
||
- частоту дискретизации TX Pluto+;
|
||
- частоту дискретизации RX RTL-SDR;
|
||
- центральную частоту TX Pluto+;
|
||
- центральную частоту RX RTL-SDR;
|
||
- усиление TX Pluto+;
|
||
- фактически выбранную ступень усиления RTL-SDR.
|
||
|
||
Для каждого параметра в отчёте и метаданных хранятся отдельные поля
|
||
`requested` и `actual`. Если API не предоставляет независимого чтения
|
||
обратно, поле `actual` имеет значение `N/A`, а не копию запрошенного
|
||
значения. Передача не начинается, если частота дискретизации или несущая
|
||
не прочитаны обратно либо отличаются от запрошенных больше, чем допускает
|
||
API устройства и заранее установленная проверка.
|
||
|
||
## 6. Двухтоновая калибровка
|
||
|
||
Перед BPSK Pluto+ передаёт два комплексных тона, симметричных относительно
|
||
несущей:
|
||
|
||
`-Fcal` и `+Fcal`, где `Fcal = 50 кГц`.
|
||
|
||
50 кГц выбраны до измерения: оба тона находятся внутри полосы 200 кГц,
|
||
не сливаются около нуля и дают разнос 100 кГц для оценки масштаба частот.
|
||
RTL-SDR измеряет положения двух пиков относительно своей настроенной
|
||
несущей: `f_low` и `f_high`.
|
||
|
||
### 6.1. Рассогласование несущей
|
||
|
||
`carrier_offset_hz = (f_low + f_high) / 2`
|
||
|
||
`carrier_offset_ppm = carrier_offset_hz / 435000000 * 1e6`
|
||
|
||
Положительный результат означает, что принятый спектр сдвинут вверх по
|
||
частоте. Для компенсации сырые комплексные отсчёты умножаются на:
|
||
|
||
`exp(-j * 2*pi*carrier_offset_hz*n/Fs_rx_actual)`
|
||
|
||
Знак поправки проверяется независимо: после компенсации среднее положение
|
||
двух тонов должно стать ближе к нулю. Рассогласование несущей не должно
|
||
подменяться оценкой ошибки частоты дискретизации.
|
||
|
||
### 6.2. Относительная ошибка частот дискретизации
|
||
|
||
`clock_scale = (f_high - f_low) / (2*Fcal)`
|
||
|
||
`sample_clock_error_ppm = (clock_scale - 1) * 1e6`
|
||
|
||
Здесь положительная ошибка означает, что масштаб передающего такта больше
|
||
масштаба приёмного. Для перехода принятых отсчётов на временную сетку
|
||
передатчика ожидаемая длина после передискретизации равна:
|
||
|
||
`len_corrected = round(len_received * clock_scale)`
|
||
|
||
Направление этой операции не принимается на веру. Оно подтверждается
|
||
машинными тестами из раздела 8. После передискретизации накопленная ошибка
|
||
символьного времени должна уменьшаться.
|
||
|
||
### 6.3. Начальная фаза выбора отсчёта символа
|
||
|
||
После грубой CFO-коррекции и передискретизации приёмник отдельно ищет
|
||
начальную фазу выбора отсчёта в диапазоне от 0 до 119 номинальных
|
||
отсчётов на символ. Это не CFO и не ошибка такта. В результатах отдельно
|
||
хранятся:
|
||
|
||
- `carrier_offset_hz` и `carrier_offset_ppm`;
|
||
- `clock_scale` и `sample_clock_error_ppm`;
|
||
- `symbol_sample_phase` и остаточная ошибка символьного времени.
|
||
|
||
### 6.4. Формальное определение шумового фона
|
||
|
||
Шумовой фон и превышение пиков вычисляются одинаковым детерминированным
|
||
алгоритмом:
|
||
|
||
1. Из комплексных отсчётов вычитается среднее.
|
||
2. Оценивается спектральная плотность мощности методом Welch с окном Hann,
|
||
`nfft = nperseg = 65536` и перекрытием 50 процентов.
|
||
3. Разрешение одного БПФ вычисляется по прочитанной обратно частоте как
|
||
`delta_f = Fs_rx_actual / 65536`. При 2,4 Мвыб/с оно равно
|
||
`36,62109375 Гц`.
|
||
4. Анализируется полоса от -100 до +100 кГц относительно настроенной
|
||
несущей.
|
||
5. Нижний пик ищется в диапазоне от -80 до -20 кГц, верхний от +20 до
|
||
+80 кГц. Эти непересекающиеся окна заданы до измерения.
|
||
6. После нахождения кандидатов ожидаемых тонов из оценки шума исключаются
|
||
защитные зоны шириной +/-2 кГц вокруг измеренного положения каждого
|
||
кандидата. Каждая полузона занимает около 55 разрешающих элементов БПФ
|
||
при 2,4 Мвыб/с, поэтому утечка основного лепестка и ближайших боковых
|
||
лепестков тона не попадает в медиану шума.
|
||
7. Шумовая мощность `P_noise` равна медиане линейных значений мощности
|
||
всех оставшихся спектральных элементов анализируемой полосы.
|
||
8. Для каждого тона вычисляется
|
||
`peak_excess_db = 10*log10(P_peak/P_noise)`.
|
||
|
||
Оба пика должны превышать шумовой фон не менее чем на 10 дБ. Порог 10 дБ,
|
||
полоса анализа, окна поиска и защитные зоны зафиксированы до аппаратного
|
||
измерения. Если нет двух конечных пиков, недостаточно элементов шума или
|
||
хотя бы один пик не проходит порог, оценка этого захвата недействительна.
|
||
|
||
### 6.5. Повторы и представление недействительных оценок
|
||
|
||
Без изменения схемы выполняются три отдельных калибровочных захвата. Для
|
||
каждого захвата отдельно сохраняются:
|
||
|
||
- `f_low_hz` и `f_high_hz`;
|
||
- `low_peak_excess_db` и `high_peak_excess_db`;
|
||
- `carrier_offset_hz` и `carrier_offset_ppm`;
|
||
- `clock_scale` и `sample_clock_error_ppm`;
|
||
- остаточная CFO после коррекции;
|
||
- остаточная ошибка разноса тонов в герцах и ppm;
|
||
- признак достоверности и причина отказа.
|
||
|
||
По трём захватам вычисляются среднее, минимум, максимум и стандартное
|
||
отклонение каждой конечной оценки, а также число недействительных
|
||
захватов. Стандартное отклонение считается по совокупности всех конечных
|
||
оценок с `ddof=0`. Недействительное значение записывается как `NaN` в CSV
|
||
и как `N/A` в текстовом отчёте. Оно никогда не заменяется нулём. Если
|
||
конечных значений нет, все агрегаты этой величины равны `N/A`.
|
||
|
||
## 7. Диагностическая последовательность передачи
|
||
|
||
Аппаратная часть выполняется по ступеням. Переход к следующей ступени
|
||
разрешён только после сохранения результатов предыдущей:
|
||
|
||
1. двухтоновые калибровочные захваты;
|
||
2. известная короткая BPSK-последовательность;
|
||
3. символьная синхронизация и измерение BER известной последовательности;
|
||
4. один пакет с CRC;
|
||
5. десять пакетированных фрагментов JPEG;
|
||
6. сборка JPEG;
|
||
7. проверка размера и SHA-256.
|
||
|
||
Известная последовательность задаётся до измерения как PRBS11 длиной
|
||
2047 бит с полиномом `x^11 + x^9 + 1` и фиксированным ненулевым начальным
|
||
состоянием, записанным в метаданные. BER вычисляется прямым сравнением
|
||
каждого принятого бита с ожидаемым до упаковки в пакет и до проверки CRC.
|
||
CRC не может использоваться вместо измерения BER.
|
||
|
||
### 7.1. Контрольный опыт PRBS11 после проверки непрерывного async-приёма
|
||
|
||
Короткая запись S и длинная запись L являются двумя отдельными аппаратными
|
||
захватами. Каждый захват выполняется одним непрерывным
|
||
`rtlsdr_read_async()` и содержит в этой последовательности: входной запас,
|
||
двухтоновую калибровку, фиксированный защитный участок 0,10 с, один
|
||
начальный маркер, непрерывную PRBS11 и выходной запас. Полезная PRBS11
|
||
длится 0,25 с в S и не менее 2,0 с в L. Внутри полезной PRBS11 нет
|
||
периодической повторной синхронизации.
|
||
|
||
Оценки CFO и масштаба частоты дискретизации для обработки PRBS11 берутся
|
||
только из двух тонов в той же самой IQ-записи. Оценку из предыдущего
|
||
двухтонового опыта или из другой записи применять запрещено. Если тоны в
|
||
текущем захвате недостоверны, PRBS11 этой записи не интерпретируется.
|
||
|
||
Для обоих захватов заранее фиксируются 435 МГц, номинальные 2 400 000
|
||
отсчётов/с TX и RX, 20 000 символов/с, TX -30 дБ, запрос усиления RTL-SDR
|
||
19,7 дБ и `Fcal = 50 кГц`. Асинхронный приём использует callback 262144
|
||
байта, 15 буферов и отбрасывает первый callback как разогревочный без
|
||
перезапуска сеанса. Автоматический подбор параметров запрещён.
|
||
|
||
Одна и та же IQ-запись обрабатывается режимами A, B и C. В B и C грубая
|
||
CFO берётся из тонов этой записи; в C дополнительно применяется
|
||
`clock_scale` этих же тонов. Разрешённая защищённая тонкая CFO-коррекция не
|
||
заменяет двухтоновое измерение. Для длинной записи SRO дополнительно
|
||
оценивается независимо по накопленному дрейфу символьной фазы.
|
||
|
||
## 8. Обязательные программные проверки до аппаратного опыта
|
||
|
||
На синтетических комплексных данных проверяются четыре ошибки частоты
|
||
дискретизации: +20, -20, +100 и -100 ppm. Для каждого случая тест обязан
|
||
проверить:
|
||
|
||
- знак оценки `sample_clock_error_ppm`;
|
||
- величину оценки в заранее заданном допуске;
|
||
- направление изменения длины при передискретизации;
|
||
- уменьшение остаточной накопленной ошибки символьного времени после
|
||
поправки.
|
||
|
||
Для положительной ошибки длина должна изменяться в направлении,
|
||
предписанном формулой `round(N * clock_scale)`, для отрицательной в
|
||
противоположном. Тест должен упасть, если вместо `clock_scale` применена
|
||
обратная величина. Допуск оценки и критерий уменьшения остаточной ошибки
|
||
задаются в тесте до аппаратного измерения и печатаются в его результате.
|
||
|
||
Дополнительно синтетические тесты проверяют:
|
||
|
||
- знак грубой CFO-коррекции для положительной и отрицательной CFO;
|
||
- уменьшение остаточной CFO после поправки;
|
||
- отдельное восстановление начальной фазы выбора отсчёта символа;
|
||
- явный `N/A`, если два тона не найдены достоверно;
|
||
- формулу шумового фона и порог 10 дБ;
|
||
- BER известной последовательности до CRC;
|
||
- отсутствие ложного успеха при неполном пакете или изображении;
|
||
- формирование кода возврата только по полному набору критериев.
|
||
|
||
До прохождения этих проверок передатчик включать нельзя.
|
||
|
||
## 9. Порядок аппаратного эксперимента
|
||
|
||
1. Открыть Pluto+ успешным `iio.Context` и записать URI и идентификаторы.
|
||
2. Открыть RTL-SDR через `pyrtlsdr` и записать имя устройства и тюнера.
|
||
3. Установить и прочитать обратно параметры из раздела 5.
|
||
4. Получить отдельное подтверждение пользователя, что кабельная схема из
|
||
раздела 4 собрана и AT30S находится в разрыве.
|
||
5. Запустить один непрерывный приём RTL-SDR за 0,5 с до передачи Pluto+.
|
||
6. Выполнить три отдельных двухтоновых калибровочных захвата.
|
||
7. Сохранить оценки каждого захвата, агрегаты и не менее одного
|
||
эталонного сырого IQ-захвата.
|
||
8. Передать известную BPSK-последовательность и измерить BER.
|
||
9. Принять один пакет и проверить CRC.
|
||
10. Передать десять фрагментов JPEG и проверить критерии раздела 11.
|
||
|
||
Если любая ступень не проходит, переход к следующей запрещён. Исходные
|
||
данные и отрицательный результат сохраняются без подгонки. Изменение
|
||
одного параметра для следующего запуска оформляется как отдельное заранее
|
||
объяснённое действие.
|
||
|
||
Весь опыт принимается RTL-SDR как одна непрерывная временная
|
||
последовательность. Продолжительность приёма вычисляется из фактически
|
||
сформированной передаваемой последовательности:
|
||
|
||
`T_rx = 0,5 с + N_tx / Fs_tx_actual + 0,5 с`.
|
||
|
||
Здесь `N_tx` является фактическим числом комплексных отсчётов всей
|
||
сформированной TX-последовательности. Общая длительность опыта не задаётся
|
||
произвольной константой. Поток разрешено читать блоками, например около
|
||
262144 отсчётов, но блоки объединяются без пропусков и перестановок в одну
|
||
последовательность. Размер блока чтения является параметром реализации, а
|
||
не физическим защитным интервалом. Десять отдельных запусков приёмника для
|
||
десяти кадров запрещены, потому что они уничтожили бы наблюдаемое
|
||
накопление ошибки тактов.
|
||
|
||
Между BPSK-кадрами не добавляются новые интервалы. Используется структура
|
||
Lab042: `GUARD_SYMBOL_COUNT` импортируется из её текущей конфигурации без
|
||
копии числовой константы в Lab043, а формирование кадра повторяет ту же
|
||
последовательность переднего интервала, символов, заднего интервала и RRC.
|
||
Готовая функция Lab042 жёстко связана с 128 отсчётами на символ, поэтому
|
||
при 120 отсчётах Lab043 переиспользуются её параметры, а не скрытая копия
|
||
её глобальной частоты дискретизации. Если в дальнейшем отдельный интервал
|
||
исчезнет из Lab042, Lab043 не создаёт новый без отдельного диагностического
|
||
решения.
|
||
|
||
## 10. Три режима обработки одной записи
|
||
|
||
Одна и та же сохранённая BPSK/IQ-запись обрабатывается тремя режимами:
|
||
|
||
- режим A: без грубой CFO-коррекции и без коррекции частоты
|
||
дискретизации;
|
||
- режим B: только грубая CFO-коррекция из двухтоновой калибровки;
|
||
- режим C: грубая CFO-коррекция, коррекция частоты дискретизации и
|
||
защищённая тонкая CFO-коррекция.
|
||
|
||
Во всех режимах начальная фаза выбора отсчёта символа оценивается и
|
||
записывается отдельно. Для каждого режима сохраняются BER известной
|
||
последовательности, остаточная CFO, остаточная временная ошибка,
|
||
корреляция маркера, число найденных кадров, число разобранных заголовков и
|
||
CRC пакетов.
|
||
|
||
В режиме C защищённая функция `should_apply_cfo_correction` из
|
||
`protocol/bpsk_radio.py` остаётся тонкой коррекцией после грубого
|
||
измерения. Она не используется как единственный способ поиска сдвига в
|
||
десятки килогерц, поскольку символьная оценка неоднозначна за пределами
|
||
половины символьной скорости.
|
||
|
||
Провал режимов A или B не считается провалом лабораторной. Они являются
|
||
контрольными измерениями. Критерии передачи применяются к режиму C.
|
||
|
||
## 11. Критерии приёмки
|
||
|
||
### 11.1. Радиокритерии режима C
|
||
|
||
- найдены все 10 кадров;
|
||
- разобраны все 10 пакетов;
|
||
- CRC32 сошлась у всех 10 пакетов.
|
||
|
||
### 11.2. Прикладные критерии режима C
|
||
|
||
- восстановлены все 10 уникальных фрагментов;
|
||
- JPEG собран без заполнения отсутствующих данных;
|
||
- размер принятого JPEG совпадает с размером переданного;
|
||
- SHA-256 принятого JPEG совпадает с SHA-256 переданного.
|
||
|
||
### 11.3. Общий результат
|
||
|
||
Код возврата 0 разрешён только при одновременном выполнении:
|
||
|
||
- всех радиокритериев;
|
||
- всех прикладных критериев;
|
||
- всех обязательных программных проверок раздела 8.
|
||
|
||
Для подтверждения воспроизводимости заранее выбранная рабочая точка
|
||
запускается три раза подряд без изменения схемы и параметров. Каждый
|
||
повтор сохраняется отдельно. Три повтора являются проверкой
|
||
воспроизводимости, а не статистической оценкой вероятности отказа.
|
||
|
||
Отрицательный результат допустим и сохраняется полностью. Запрещено
|
||
автоматически поднимать усиление, менять частоту, пороги или алгоритм
|
||
синхронизации после неудачного прогона.
|
||
|
||
## 12. Измерения и артефакты
|
||
|
||
### 12.1. Измерения передачи
|
||
|
||
Для каждого запуска и каждого режима обработки сохраняются:
|
||
|
||
- запрошенные и фактические усиления, несущие и частоты дискретизации;
|
||
- число принятых отсчётов;
|
||
- отдельные оценки CFO, ошибки частоты дискретизации и начальной
|
||
символьной фазы;
|
||
- BER известной последовательности до CRC;
|
||
- число найденных кадров и разобранных заголовков;
|
||
- CRC каждого пакета;
|
||
- решение защищённой тонкой CFO-коррекции и его диагностические величины;
|
||
- корреляция маркера и корректно определённая EVM;
|
||
- число и номера восстановленных фрагментов;
|
||
- размер и SHA-256 переданного и принятого JPEG;
|
||
- длительность сигнала и полезная скорость.
|
||
|
||
Каждое число вычисляется из текущего запуска. Перенесённые константы
|
||
снабжаются ссылкой на лабораторную-источник. Невычислимая величина
|
||
записывается как `NaN` или `N/A`, но не как правдоподобный ноль.
|
||
|
||
### 12.2. План программных артефактов
|
||
|
||
Предполагаемые файлы после отдельного согласования реализации:
|
||
|
||
- `experiments/lab043_pluto_to_rtlsdr.py`;
|
||
- `tests/test_lab043_calibration.py`;
|
||
- `data/processed/lab043/lab043_calibration.csv`;
|
||
- `data/processed/lab043/lab043_frames.csv`;
|
||
- `data/processed/lab043/lab043_summary.csv`;
|
||
- `data/processed/lab043/lab043_report.txt`;
|
||
- графики калибровочного спектра, остаточной ошибки и доставки
|
||
фрагментов.
|
||
|
||
### 12.3. Эталонный сырой IQ-захват
|
||
|
||
Не менее одного полного эталонного захвата до CFO- и SRO-коррекций
|
||
сохраняется в `data/raw/lab043/` и не добавляется в Git.
|
||
|
||
Формат отсчётов: NumPy `.npy`, одномерный массив `complex64` в порядке
|
||
приёма. Нормирование исходных 8-битных I/Q отсчётов и порядок I/Q должны
|
||
быть однозначно описаны в метаданных. Рядом сохраняется UTF-8 JSON с тем
|
||
же базовым именем и полями:
|
||
|
||
- локальная метка времени и UTC;
|
||
- идентификаторы устройств и модель тюнера;
|
||
- версии Python, `pyrtlsdr`, `pyrtlsdrlib`, `librtlsdr`, `pyadi-iio` и
|
||
`pylibiio`;
|
||
- запрошенные и фактические частоты дискретизации, несущие и усиления;
|
||
- число отсчётов, длительность, dtype и порядок байтов;
|
||
- идентификатор и SHA-256 переданной формы сигнала;
|
||
- результаты калибровки, применённые к этой записи;
|
||
- SHA-256 файла `.npy`.
|
||
|
||
IQ-файл содержит всю единую последовательность приёма. Ожидаемое число
|
||
отсчётов вычисляется как `ceil(T_rx * Fs_rx_actual)`. Чтение выполняется
|
||
последовательными блоками до достижения этого числа, последний блок
|
||
обрезается только после получения требуемого количества отсчётов.
|
||
|
||
### 12.4. Разделение общего и лабораторного кода
|
||
|
||
Общие математические примитивы обнаружения двух известных тонов, оценки
|
||
грубой CFO и относительной ошибки частот дискретизации, грубой частотной
|
||
коррекции и передискретизации размещаются в `protocol/bpsk_radio.py` либо
|
||
в другом подходящем существующем модуле `protocol/`. Каждый такой перенос
|
||
сопровождается быстрым синтетическим тестом.
|
||
|
||
В `experiments/lab043_pluto_to_rtlsdr.py` остаются сценарий лабораторной,
|
||
конкретное `Fcal`, три калибровочных захвата, методика оценки шума Lab043,
|
||
режимы A/B/C, PRBS11, контрольный пакет, JPEG, отчётные артефакты,
|
||
критерии приёмки и аппаратная последовательность. Общий код не зависит от
|
||
конкретного JPEG и номера лабораторной.
|
||
|
||
## 13. Точка остановки перед аппаратным опытом
|
||
|
||
Программная реализация и синтетические проверки разрешены. Перед
|
||
аппаратным опытом необходимо отдельно:
|
||
|
||
1. пройти все обязательные программные проверки раздела 8;
|
||
2. повторно проверить доступность устройств и чтение параметров обратно;
|
||
3. получить подтверждение пользователя о схеме и отдельное разрешение на
|
||
включение TX.
|
||
|
||
Способ Python-доступа к RTL-SDR уже выбран и не является вопросом точки
|
||
остановки.
|
||
|
||
До отдельного разрешения передатчик не включается, усиление Pluto+ не
|
||
изменяется, аппаратная калибровка и передача тонов, BPSK или JPEG не
|
||
выполняются. Операции `git add`, `commit`, `push`, `pull` и `fetch` также
|
||
не выполняются.
|