From 92477a4632d2172578c859afd823e6d3b39f42a6 Mon Sep 17 00:00:00 2001 From: LittleSam129 <1qwe432@gmail.com> Date: Thu, 10 Sep 2026 13:58:11 +0300 Subject: [PATCH] Lab056: compare 20 and 500 ksymbol/s in controlled RF session --- PROJECT_LOG.md | 226 ++++++++ data/processed/lab056/acceptance.json | 76 +++ data/processed/lab056/ota_correction.json | 135 +++++ data/processed/lab056/preparation.json | 173 ++++++ data/processed/lab056/rf_analysis.json | 530 +++++++++++++++++ data/processed/lab056/rf_overview.png | Bin 0 -> 310041 bytes data/processed/lab056/rf_result.json | 336 +++++++++++ .../lab056/rf_session_authorization.json | 30 + .../processed/lab056/rf_session_commands.json | 262 +++++++++ .../lab056/rx_preflight_commands.json | 218 +++++++ data/processed/lab056/rx_preflight_plan.json | 26 + .../processed/lab056/rx_preflight_result.json | 114 ++++ data/processed/lab056/software_equal.json | 489 ++++++++++++++++ .../lab056/software_equal_ota_summary.json | 532 ++++++++++++++++++ data/processed/lab056/software_minus6db.json | 489 ++++++++++++++++ .../lab056/software_minus6db_ota_summary.json | 532 ++++++++++++++++++ docs/LABS_INDEX.md | 45 ++ docs/lab056_current_state.md | 326 +++++++++++ docs/lab056_rf_result.md | 222 ++++++++ docs/lab056_rx_preflight.md | 98 ++++ experiments/lab054_hardware_control.py | 359 ++++++++++++ experiments/lab056_abab_energy.py | 312 ++++++++++ experiments/lab056_capture_runner.py | 263 +++++++++ tests/test_hackrf_process_check.py | 159 ++++++ tests/test_lab054_hardware_control.py | 140 +++++ tests/test_lab056_preparation.py | 248 ++++++++ tools/hackrf_process_check.py | 178 ++++++ 27 files changed, 6518 insertions(+) create mode 100644 data/processed/lab056/acceptance.json create mode 100644 data/processed/lab056/ota_correction.json create mode 100644 data/processed/lab056/preparation.json create mode 100644 data/processed/lab056/rf_analysis.json create mode 100644 data/processed/lab056/rf_overview.png create mode 100644 data/processed/lab056/rf_result.json create mode 100644 data/processed/lab056/rf_session_authorization.json create mode 100644 data/processed/lab056/rf_session_commands.json create mode 100644 data/processed/lab056/rx_preflight_commands.json create mode 100644 data/processed/lab056/rx_preflight_plan.json create mode 100644 data/processed/lab056/rx_preflight_result.json create mode 100644 data/processed/lab056/software_equal.json create mode 100644 data/processed/lab056/software_equal_ota_summary.json create mode 100644 data/processed/lab056/software_minus6db.json create mode 100644 data/processed/lab056/software_minus6db_ota_summary.json create mode 100644 docs/lab056_current_state.md create mode 100644 docs/lab056_rf_result.md create mode 100644 docs/lab056_rx_preflight.md create mode 100644 experiments/lab054_hardware_control.py create mode 100644 experiments/lab056_abab_energy.py create mode 100644 experiments/lab056_capture_runner.py create mode 100644 tests/test_hackrf_process_check.py create mode 100644 tests/test_lab054_hardware_control.py create mode 100644 tests/test_lab056_preparation.py create mode 100644 tools/hackrf_process_check.py diff --git a/PROJECT_LOG.md b/PROJECT_LOG.md index e4df771..9994d04 100644 --- a/PROJECT_LOG.md +++ b/PROJECT_LOG.md @@ -2218,3 +2218,229 @@ HEAD прежний0368c6d3e930f4d245e056223fd4e5c4f70e6b49, main; предыд изменения Lab054 сохранены. Git add/commit/push/pull/fetch не выполнялись. Следующий этап: STOP и согласование измерительной схемы, приборов и допустимой частоты; никакого автоматического аппаратного продолжения. + +# Запись 047 + +## Дата + +9 сентября 2026 года + +## Тема + +Lab055 — фиксация результата; Lab056 — программная подготовка эфирного ABAB + +## Выполнено + +По новому явному разрешению пользователя Lab055 зафиксирована коммитом +5add95ecb8865f59075bbbced08d97b183fb3b48 с сообщением +Lab055: audit received signal energy across symbol rates. +В коммите семь файлов только Lab055: анализатор, тесты, отчёт, два JSON, +запись 046 и раздел индекса. Предшествующие изменения Lab054 сохранены +незакоммиченными. Перед коммитом quick_gate 823/28/13 PASS, pytest 823 passed. +Push не выполнялся. Исторический Lab054 NOT_A, 0/16, не изменён; +повторная проверка SHA-256 всех 34 входов Lab055 не выявила изменений. + +Прямой выбор пользователя — эфирный опыт вместо предпочтительного кабеля +из приложения. Подготовлен один TX-файл ABAB: 20/500/20/500 ксимв/с, +прежние PRBS7/BPSK/RRC, Fs 8 Мвыб/с и цифровая несущая +50 кГц. +Созданы experiments/lab056_abab_energy.py, lab056_capture_runner.py, +tests/test_lab056_preparation.py, docs/lab056_current_state.md и малые +результаты data/processed/lab056. Большие CS8 находятся в data/raw/lab056. + +TX RMS всего сегмента A/B: 44,004413/44,001925 код; разница мощности +−0,000491 дБ. Активные участки отдельно: −0,042606 дБ; клиппинг 0. +TX 10 588 544 отсчёта, 1,323568 с; RX планируется 3 с с упреждением 0,5 с. +A1=A2 и B1=B2 побайтно. Пять gaps по 0,1 с содержат нулевой цифровой IQ +при работающем TX-процессе: это не доказательство выключенного RF. + +Анализатор сохраняет полную и AC-мощность RX, локальный фон, устойчивую +разность мощностей, комплексный коэффициент передачи, согласованную +компоненту, остаток и интегральный спектр. Мощность и энергия символа +выводятся отдельно. RX не выравнивается по амплитуде после приёма. +Искусственные записи с одинаковым усилением и падением B на 6,020600 дБ +обработаны успешно: оценки разницы коэффициента передачи соответственно ++0,001786/−0,002894 дБ и −6,014144/−6,022175 дБ для двух пар. +Это программные проверки, не аппаратный результат. + +Подготовлен RX-first runner с единственной конечной TX-попыткой, без повтора, +проверкой процессов, SHA, размеров, счётчиков потерь и cleanup. Common clock +проверен только mock-тестами; реальные reg29/CLKIN сейчас NOT_PERFORMED. +Частота не назначена: 1400 МГц пересекает запрещённую для излучения полосу +1400–1427 МГц (ITU RR2024, п. 5.340). Для будущего опыта нужны допустимая +частота/полоса, страна и подтверждение антенн/неизменной геометрии. +Эфирный ABAB измеряет весь путь, включая антенны и распространение; +он не изолирует внутренние аппаратные потери HackRF и не измеряет dBm. + +Verifier независимо пересчитал коэффициенты, проверил TX и mock-отказы. +Воспроизведённая ошибка разбора счётчиков с префиксом RX/TX исправлена; +повторная проверка закрыла находку. Остаточных воспроизведённых находок нет. +34 целевых теста PASS; итоговые quick_gate 857/30/13 PASS, +pytest 857 passed, 0 failed, 96,50 с; git diff --check PASS. +HackRF не запускался, RF TX=0. Lab056 не коммитилась; push не выполнялся. +Следующий этап: STOP, согласование допустимой эфирной конфигурации и отдельное +разрешение на конкретный однократный RF-сеанс перед аппаратным preflight. + +# Запись 048 + +## Дата + +10 сентября 2026 года + +## Тема + +Lab056 — принятое пользователем изменение методики на контролируемый OTA + +## Выполнено + +Пользователь сообщил об отсутствии необходимого SMA-переходника и осознанно +выбрал эфирный ABAB. Кабельный TX → 30 дБ → RX отложен до получения +переходника как отдельная проверка. Центральную частоту определяет пользователь: +RF_FREQ = USER_AUTHORIZED_RF_HZ. Конкретное значение пока не сообщено; +обязательные поля страны/регуляторной полосы убраны из параметров runner, +национальная регуляторика повторно не исследовалась. В отчёте подготовлены +поля антенн, расстояния, ориентации/поляризации, LOS/NLOS и частоты. + +Готовый ABAB waveform, метаданные, прежние результаты и исходная сводка +857 passed сохранены. RMS A/B 44,004413/44,001925 код, разница мощности +−0,000491 дБ, TX 1,323568 с, RX 3 с. Усиления TX10/RX24/24, +Fs 8 Мвыб/с и несущая +50 кГц не менялись; внешних PA/LNA нет. + +В runner оформлен отдельный RX-only preflight: common clock с обоими +reg29=0x26 и SLAVE CLKIN=DETECTED, 0,1 с приёма фона для проверки уровня, +сохранение результата и cleanup, затем STOP перед отдельным разрешением TX. +При частоте UNKNOWN аппаратных действий нет. capture_once требует PASS +этой конфигурации, отдельной авторизации и свежей проверки опоры. +При клиппинге до TX — RF TX=0; при обнаружении только в записи ABAB — +RF TX=1 и отказ без повтора. Счётчик уже выполненной передачи не обнуляется. +Ни частота, ни gains автоматически не подбираются. + +Добавлен явный комплексный h прежней модели, сводки X/Y/Z и повторяемость +A2/A1, B2/B1. Те же искусственные IQ прочитаны повторно с новыми именами +выходных JSON. Для равного усиления X/Y/Z −0,046404/−0,000553/−14,025804 дБ; +для ослабления B на 6,020600 дБ: −6,039124/−6,018156/−20,018524 дБ. +Это программные значения, не аппаратный результат Lab056. Эфирный опыт +будет характеризовать весь путь, а не отдельно внутренние потери HackRF. + +44 целевых теста PASS. Итоговые quick_gate 867/30/13 PASS, +pytest 867 passed, 0 failed, 89,32 с; git diff --check PASS. +Verifier независимо исполнил 44 случая с данными в памяти, без записи +и оборудования; воспроизведённых находок нет. Исторический Lab054 NOT_A +сохранён. HEAD 5add95ecb8865f59075bbbced08d97b183fb3b48, Lab056 не коммитилась, +push не выполнялся. Аппаратных команд нет, RF TX=0. +Следующий этап: получить RF_FREQ, выполнить разрешённый RX-only аппаратный +preflight, остановиться с кратким отчётом и ждать отдельного разрешения +на один ABAB-сеанс. Кабельный контроль и PA автоматически не добавляются. + +# Запись 049 + +## Дата + +10 сентября 2026 года + +## Тема + +Lab056 — аппаратный common-clock и RX-only preflight на частоте пользователя + +## Выполнено + +Пользователь задал RF_FREQ=1400000000 Гц только для текущей лабораторной +проверки. Это не рабочая частота SDR_Rover; ориентир полевых работ около +180 МГц и варианты 50/144 МГц здесь не исследуются. Задана геометрия OTA: +имеющиеся антенны 1400 МГц, LOS, неподвижное оборудование, одинаковые +поляризация/ориентация, расстояние примерно 3–5 м. Точные модели антенн +и измеренное расстояние не сообщены; описание сохранено без выдуманных данных. + +Выполнен только разрешённый аппаратный preflight. Инвентаризация подтвердила +MASTER ...323b97d3 и SLAVE ...2e5327d3. После коротких RX-start обоих устройств +MASTER reg29=0x26, SLAVE reg29=0x26, SLAVE CLKIN=DETECTED; опора обнаружена +первым запросом через 67,787 мс ожидания. Затем SLAVE записал 800 000 +комплексных отсчётов, 0,1 с, на той же частоте, Fs 8 Мвыб/с, RX24/24 дБ, +RF amplifier/Bias-Tee OFF. Внешних PA/LNA нет. TX не запускался. + +CS8 1 600 000 байт, SHA-256 +c4257f26e4cc8562eb32228f9a50fdeb055879c928af0744cdf4a81cf7cd085b. +RMS 2,203152571 код, мощность 4,85388125 код², AC-мощность 0,6658039582 код², +максимумы абсолютных I/Q 4/6 код. Клиппинг 0 из 800 000 отсчётов, overruns 0. +Отсутствие клиппинга фона без TX не гарантирует отсутствие перегрузки +при будущем включении TX. После проверки CLKOUT обеих плат выключены, +процессы CLEAR до/после, cleanup без ошибок. + +Сохранены исходный RX, preflight_result/attempt, план и журнал фактических +команд. Три hackrf_transfer-команды были только RX: два коротких запуска +для опоры и запись фона; TX-команд 0. Отчёт docs/lab056_rx_preflight.md. +Verifier только по сохранённым файлам подтвердил 12 команд, регистры, +CLKIN, параметры и cleanup; пересчитал SHA и мощность/клиппинг вторым +способом. Воспроизведённых расхождений нет, PASS, аппаратных команд не было. +Код и готовый TX не менялись; SHA совпадают с проверенной версией. +Последние программные проверки этой версии: 44 целевых теста, +quick_gate 867/30/13 PASS, pytest 867 passed. Git diff --check PASS. +Lab054 NOT_A сохранён. HEAD 5add95ecb8865f59075bbbced08d97b183fb3b48; +Lab056 не коммитилась, push не выполнялся. RF TX=0. +Следующий этап: STOP с техническим READY FOR SINGLE ABAB TX=YES; +дождаться отдельного разрешения пользователя на единственный ABAB TX. + +# Запись 050 + +## Дата + +10 сентября 2026 года + +## Тема + +Lab056 — единственный OTA ABAB 20/500 ксимв/с; большой провал не воспроизведён + +## Выполнено + +После отдельного явного разрешения пользователя выполнен один конечный +ABAB TX с неизменным ранее подготовленным файлом 10 588 544 отсчёта, +1,323568 с. RX запущен первым и сохранил 24 000 000 комплексных отсчётов, +48 000 000 байт, 3 с. Частота 1400000000 Гц только для Lab056, +Fs 8 Мвыб/с, TX10/RX24/24 дБ, несущая +50 кГц, прежние PRBS7/BPSK/RRC; +RF amplifier/Bias-Tee OFF, внешних PA/LNA нет. Геометрия по заданию +пользователя: имеющиеся антенны 1400 МГц, LOS, примерно 3–5 м, +неподвижность и одинаковые поляризация/ориентация. Параметры между A/B +не менялись. Код, пороги, timing, FEC/CRC и цифровой TX не менялись. + +Свежая опора перед сеансом PASS: оба reg29=0x26, SLAVE CLKIN=DETECTED +через 137,359 мс штатного ожидания. По журналу RX стартовал на 0,517342 с +раньше TX. RX overruns=0, TX underruns=0, клиппинг 0 до и после ABAB. +Полный RX RMS 2,235380477 код, максимумы абсолютных I/Q 5/6 код. +Все 14 аппаратных команд сохранены; среди них один TX без повтора. +CLKOUT после опыта выключены, процессы CLEAR, cleanup без ошибок. + +Подготовленный анализатор нашёл четыре сегмента с корреляцией 0,384366. +Начала A1/B1/A2/B2 в RX: 5 254 791 / 7 709 991 / 10 149 062 / +12 604 263; общий сдвиг относительно TX расходится лишь на один отсчёт. +Все активные окна 0,2048 с, порядок ABAB и gaps подтверждены. +Полезные мощности после фона A1/B1/A2/B2: +0,462680958 / 0,476010015 / 0,414075173 / 0,423007891 код². +Согласованные компоненты: 0,312320987 / 0,297815525 / +0,299566893 / 0,285847043 код². Raw/AC/фон/комплексный h/остаток/спектры +по каждому сегменту приведены в docs/lab056_rf_result.md и rf_analysis.json. + +Итоги по средним линейным мощностям: +X, принятая мощность B/A после вычитания фона: +0,108895 дБ; +Y, коэффициент передачи abs(h)² B/A: −0,163042 дБ; +Z, энергия символа этой же принятой мощности: −13,870505 дБ. +Повтор A2/A1 по мощности −0,482024 дБ, B2/B1 −0,512676 дБ; +по abs(h)² −0,181074/−0,178136 дБ. Парные оценки B/A близки. + +Прежний провал порядка 15,41 дБ в одной короткой OTA-сессии не воспроизвёлся. +Это не выделяет собственные потери HackRF из антенн и распространения +и не объясняет причину старого различия раздельных опытов. Кабельный контроль +после SMA-переходника остаётся отдельным необходимым этапом для такого +разделения. PA не назначен. Packet/PHY PASS, видео и FEC не исследовались. +Исторический Lab054 NOT_A, 0/16 сохранён; 34 исходных SHA Lab055 не изменились. + +Verifier только по сохранённым файлам независимо подтвердил команды, +SHA/размеры/клиппинг, четыре начала, мощности/фон и комплексный МНК; +расчёты согласованы до 1e−12, воспроизведённых находок нет. +RX SHA e336dd653fa554058052fcf851e9f2462f66b8cf7c710815ca2b9a09ffc23ad4. +TX SHA 5b34bbe1a8e6d037d2d6d367a74e9eb84e8940db7da61600ffaa7f7497d4f600. +Сохранены raw IQ, журналы, машинная сводка rf_result.json и график +data/processed/lab056/rf_overview.png. Код прежний: последние проверки +44 целевых теста, quick_gate 867/30/13, pytest 867 passed; diff check PASS. +HEAD 5add95ecb8865f59075bbbced08d97b183fb3b48. Lab056 не коммитилась, +push не выполнялся. Выполненных TX=1, сейчас RF TX=0, повторов нет. +Следующий этап: STOP и рассмотрение отчёта пользователем; никакого +автоматического второго RF-сеанса, кабельного контроля или добавления PA. diff --git a/data/processed/lab056/acceptance.json b/data/processed/lab056/acceptance.json new file mode 100644 index 0000000..945081c --- /dev/null +++ b/data/processed/lab056/acceptance.json @@ -0,0 +1,76 @@ +{ + "date": "2026-09-09", + "stage": "SOFTWARE_READY_RF_CONFIGURATION_PENDING", + "lab055_commit": "5add95ecb8865f59075bbbced08d97b183fb3b48", + "new_head": "5add95ecb8865f59075bbbced08d97b183fb3b48", + "lab055_commit_files": 7, + "lab055_inputs_sha256_rechecked": 34, + "lab055_inputs_changed": [], + "lab054_official_result": "NOT_A", + "lab054_packets": "0/16", + "rf_tx": 0, + "hardware_commands_executed": 0, + "hardware_common_clock_preflight": "NOT_PERFORMED", + "mock_common_clock": "PASS", + "rf_frequency_hz": null, + "physical_path": "OTA_REQUESTED_FREQUENCY_AND_GEOMETRY_PENDING", + "waiting_for_explicit_rf_authorization": true, + "lab056_committed": false, + "push_performed": false, + "targeted_tests": { + "passed": 34, + "failed": 0 + }, + "quick_gate": { + "command": "python tools/quick_gate.py", + "passed": true, + "core_tests": 857, + "functional_labs": 30, + "skipped_labs": 13 + }, + "pytest": { + "command": "python -m pytest tests/ -q -p no:cacheprovider", + "passed": 857, + "failed": 0, + "elapsed_seconds": 96.5 + }, + "diff_check": "PASS", + "verifier": { + "mode": "READ_ONLY_SOFTWARE", + "remaining_reproduced_findings": 0, + "counter_parser_finding": "FIXED_AND_REPRODUCIBLY_CLOSED" + }, + "synthetic_equal": { + "passed": true, + "expected_gain_difference_db": 0.0, + "measured_pairs_db": [ + 0.0017861283874782213, + -0.0028938012026523408 + ] + }, + "synthetic_minus6db": { + "passed": true, + "expected_gain_difference_db": -6.020599913279624, + "measured_pairs_db": [ + -6.014143555521402, + -6.022174975174189 + ] + }, + "power_units": "RX_CODE_SQUARED_NOT_CALIBRATED_RF_WATTS", + "gap_is_zero_digital_iq_not_rf_off": true, + "ota_scope": "ENTIRE_TX_ANTENNA_PROPAGATION_RX_PATH_NOT_ISOLATED_HACKRF", + "artifact_sha256": { + "experiments/lab056_abab_energy.py": "a36d277998b9b07c97eed0cfedec98ffed1ee2ea44e150f870b191b9a2d957c7", + "experiments/lab056_capture_runner.py": "4ccfec4bfd123602d61dba5107e5ac7763326aaaf6cdb2b1e7dbcfdfcb059488", + "tests/test_lab056_preparation.py": "74b428096a28c91ce603d3e13ad03ef9526a1a5a4be2d5001ec61441a4d1da1e", + "experiments/lab054_hardware_control.py": "199046f939d39eaa7b2a5769149dd43052b353bba79b4cccba60b7ab72071101", + "experiments/lab055_energy_audit.py": "ac4da1e31bc20b1740aebfab31f1368adb4ed6afe845ba8c4e45f579ea0f3753", + "data/processed/lab056/preparation.json": "535375d08a0699ac4be31992ddbb6c5d175b3156a0a3b508b45d7cb567c24071", + "data/processed/lab056/software_equal.json": "2c8bd05a0a1d488961a9a353c3ba9bf624e929792b66371bdb2b190b2cf22ca8", + "data/processed/lab056/software_minus6db.json": "c015de2d5238d5d3c1ea9d56b0e4a5da200f2e0f14e3640fa27a396ffd489f67", + "data/raw/lab056/tx_abab.cs8": "5b34bbe1a8e6d037d2d6d367a74e9eb84e8940db7da61600ffaa7f7497d4f600", + "data/raw/lab056/tx_metadata.json": "535375d08a0699ac4be31992ddbb6c5d175b3156a0a3b508b45d7cb567c24071", + "data/raw/lab056/synthetic_equal.cs8": "a88afcc1bbeb50092f9f5baca6eb607d25daf508e0fafcdcada318818d9ffd62", + "data/raw/lab056/synthetic_minus6db.cs8": "a189c1ffaf029983d41f7d87e262cbbc28ba740fc8915a75e41ee0adec9c1fe6" + } +} diff --git a/data/processed/lab056/ota_correction.json b/data/processed/lab056/ota_correction.json new file mode 100644 index 0000000..db64c5e --- /dev/null +++ b/data/processed/lab056/ota_correction.json @@ -0,0 +1,135 @@ +{ + "date": "2026-09-10", + "stage": "OTA_CORRECTION_READY_WAITING_USER_RF_FREQ", + "head": "5add95ecb8865f59075bbbced08d97b183fb3b48", + "method": "CONTROLLED_OTA_ABAB", + "reason": "USER_REPORTED_MISSING_SMA_ADAPTER", + "conducted_test": "DEFERRED_SEPARATE_CONTROL_AFTER_ADAPTER", + "rf_frequency_hz": null, + "rf_frequency_source": "USER_AUTHORIZED_RF_HZ", + "country_required": false, + "national_regulatory_research_performed": false, + "geometry": { + "tx_antenna": null, + "rx_antenna": null, + "distance_m": null, + "orientation": null, + "los_nlos": null + }, + "rf_tx": 0, + "hardware_commands_executed": 0, + "hardware_common_clock": "NOT_PERFORMED", + "next_step": "USER_RF_FREQ_THEN_RX_ONLY_PREFLIGHT_THEN_STOP_BEFORE_TX_AUTHORIZATION", + "preflight_rx_seconds": 0.1, + "rx_capture_seconds": 3.0, + "tx_seconds": 1.323568, + "preflight_background_does_not_prove_no_clipping_during_tx": true, + "saturation_policy": { + "before_tx": "STOP_WITH_TX_COUNT_0", + "during_tx": "PRESERVE_ACTUAL_TX_COUNT_1_AND_STOP_NO_RETRY" + }, + "baseline_acceptance_preserved": { + "path": "data/processed/lab056/acceptance.json", + "sha256": "ba48c2bb22947333aee99d5e72b0c6b661e617b1047b2672cb2d4c21ef721320", + "pytest_passed": 857 + }, + "targeted_tests": { + "passed": 44, + "failed": 0 + }, + "quick_gate": { + "passed": true, + "core_tests": 867, + "functional_labs": 30, + "skipped_labs": 13 + }, + "pytest": { + "command": "python -m pytest tests/ -q -p no:cacheprovider", + "passed": 867, + "failed": 0, + "elapsed_seconds": 89.32 + }, + "verifier": { + "mode": "READ_ONLY_IN_MEMORY", + "cases_passed": 44, + "remaining_reproduced_findings": 0 + }, + "original_segment_measurements_and_pairs_unchanged": true, + "synthetic_comparison_summaries": { + "equal": { + "repeatability": [ + { + "comparison": "A2/A1", + "raw_rx_power_difference_db": -0.0012085532551280598, + "background_difference_db": -0.0017255178918689754, + "received_power_difference_db": -0.005652782408264756, + "channel_gain_difference_db": -0.0023081300526506692, + "matched_component_difference_db": -0.00230813005264874 + }, + { + "comparison": "B2/B1", + "raw_rx_power_difference_db": 0.00036367664985406537, + "background_difference_db": -0.011492673362299905, + "received_power_difference_db": 0.004534904727870617, + "channel_gain_difference_db": -0.006988059642781434, + "matched_component_difference_db": -0.006988059642780951 + } + ], + "averaging": "RATIO_OF_MEAN_LINEAR_POWERS_B1_B2_OVER_A1_A2", + "received_power_difference_db": -0.04640374115997541, + "channel_gain_difference_db": -0.000552584218408658, + "energy_per_symbol_difference_db": -14.025803827880353, + "energy_basis": "BACKGROUND_SUBTRACTED_RECEIVED_POWER_DIVIDED_BY_SYMBOL_RATE" + }, + "minus6db": { + "repeatability": [ + { + "comparison": "A2/A1", + "raw_rx_power_difference_db": -0.0012085532551280598, + "background_difference_db": -0.0017255178918689754, + "received_power_difference_db": -0.005652782408264756, + "channel_gain_difference_db": -0.0023081300526506692, + "matched_component_difference_db": -0.00230813005264874 + }, + { + "comparison": "B2/B1", + "raw_rx_power_difference_db": 0.0016044036249902335, + "background_difference_db": -0.011492673362299905, + "received_power_difference_db": 0.016513577295241087, + "channel_gain_difference_db": -0.0103395497054386, + "matched_component_difference_db": -0.010339549705438118 + } + ], + "averaging": "RATIO_OF_MEAN_LINEAR_POWERS_B1_B2_OVER_A1_A2", + "received_power_difference_db": -6.039124271880495, + "channel_gain_difference_db": -6.018156341674954, + "energy_per_symbol_difference_db": -20.01852435860087, + "energy_basis": "BACKGROUND_SUBTRACTED_RECEIVED_POWER_DIVIDED_BY_SYMBOL_RATE" + } + }, + "lab055_inputs_rechecked": 34, + "lab055_inputs_changed": [], + "lab054_official": "NOT_A, 0/16", + "preserved_artifact_sha256": { + "experiments/lab054_hardware_control.py": "199046f939d39eaa7b2a5769149dd43052b353bba79b4cccba60b7ab72071101", + "experiments/lab055_energy_audit.py": "ac4da1e31bc20b1740aebfab31f1368adb4ed6afe845ba8c4e45f579ea0f3753", + "data/processed/lab056/preparation.json": "535375d08a0699ac4be31992ddbb6c5d175b3156a0a3b508b45d7cb567c24071", + "data/processed/lab056/software_equal.json": "2c8bd05a0a1d488961a9a353c3ba9bf624e929792b66371bdb2b190b2cf22ca8", + "data/processed/lab056/software_minus6db.json": "c015de2d5238d5d3c1ea9d56b0e4a5da200f2e0f14e3640fa27a396ffd489f67", + "data/raw/lab056/tx_abab.cs8": "5b34bbe1a8e6d037d2d6d367a74e9eb84e8940db7da61600ffaa7f7497d4f600", + "data/raw/lab056/tx_metadata.json": "535375d08a0699ac4be31992ddbb6c5d175b3156a0a3b508b45d7cb567c24071", + "data/raw/lab056/synthetic_equal.cs8": "a88afcc1bbeb50092f9f5baca6eb607d25daf508e0fafcdcada318818d9ffd62", + "data/raw/lab056/synthetic_minus6db.cs8": "a189c1ffaf029983d41f7d87e262cbbc28ba740fc8915a75e41ee0adec9c1fe6" + }, + "new_artifact_sha256": { + "experiments/lab056_abab_energy.py": "323408b3bc1aa02c8b2f2855cd6295ac2efd99f13afec2ca0c872aa013a78f96", + "experiments/lab056_capture_runner.py": "24c17060b8b3e3f6899f9e922ae818e7ae2efba456c5f5cada7c69b5e5429334", + "tests/test_lab056_preparation.py": "d48aef79ae2455ca397862082a89f4c5f9a7e4d678e9b464c8489dd0e319a5ac", + "docs/lab056_current_state.md": "1accf50e4b67ec60fd6e8f041048d4b4b4a04551ebb51e43dafb0d52e40c7e35", + "data/processed/lab056/software_equal_ota_summary.json": "2a04b074eb9f59e726fd9cb70744498384ce4a5aa3c3bd7e92ae21f4e55d05a1", + "data/processed/lab056/software_minus6db_ota_summary.json": "01eb38bdc7f3bbd5bf468959cf7395a2b865318d6340cc9a70683576606cd3e0" + }, + "lab056_commit": false, + "push": false, + "diff_check": "PASS" +} diff --git a/data/processed/lab056/preparation.json b/data/processed/lab056/preparation.json new file mode 100644 index 0000000..2585063 --- /dev/null +++ b/data/processed/lab056/preparation.json @@ -0,0 +1,173 @@ +{ + "stage": "PREPARATION_ONLY", + "rf_tx": 0, + "rf_frequency_hz": null, + "physical_path": "OTA_REQUESTED_FREQUENCY_AND_GEOMETRY_PENDING", + "sample_rate_hz": 8000000, + "carrier_hz": 50000, + "tx_samples": 10588544, + "tx_bytes": 21177088, + "tx_seconds": 1.323568, + "rx_samples": 24000000, + "rx_seconds": 3.0, + "rx_lead_seconds": 0.5, + "gap_seconds": 0.1, + "gap_is_zero_digital_iq_not_rf_off": true, + "tx_sha256": "5b34bbe1a8e6d037d2d6d367a74e9eb84e8940db7da61600ffaa7f7497d4f600", + "segments": [ + { + "label": "A1", + "symbol_rate": 20000, + "start": 800000, + "samples": 1655200, + "active_start": 808400, + "active_samples": 1638400, + "whole": { + "samples": 1655200, + "mean_i": -3.624939584340261e-06, + "mean_q": -8.458192363460609e-06, + "power_code2": 1936.3883820686322, + "ac_power_code2": 1936.3883820685476, + "rms_code": 44.00441321127498, + "peak_magnitude_code": 69.29646455628166, + "max_abs_i": 68.0, + "max_abs_q": 69.0, + "papr_db": 3.9442968742176006, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.09681941910343161 + }, + "active": { + "samples": 1638400, + "mean_i": 2.99072265625e-05, + "mean_q": -0.0008270263671875, + "power_code2": 1956.0524084472656, + "ac_power_code2": 1956.0524077623986, + "rms_code": 44.22728126900031, + "peak_magnitude_code": 69.29646455628166, + "max_abs_i": 68.0, + "max_abs_q": 69.0, + "papr_db": 3.9004166907590005, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.09780262042236328 + } + }, + { + "label": "B1", + "symbol_rate": 500000, + "start": 3255200, + "samples": 1639072, + "active_start": 3255536, + "active_samples": 1638400, + "whole": { + "samples": 1639072, + "mean_i": 0.00011042833993869702, + "mean_q": -0.002146336463559868, + "power_code2": 1936.1693793805275, + "ac_power_code2": 1936.169374761573, + "rms_code": 44.00192472359053, + "peak_magnitude_code": 68.6804193347711, + "max_abs_i": 66.0, + "max_abs_q": 68.0, + "papr_db": 3.8672252879366917, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.003872338758761055 + }, + "active": { + "samples": 1638400, + "mean_i": -8.544921875e-06, + "mean_q": -0.002210693359375, + "power_code2": 1936.9563952636718, + "ac_power_code2": 1936.9563903764335, + "rms_code": 44.010866786098084, + "peak_magnitude_code": 68.6804193347711, + "max_abs_i": 66.0, + "max_abs_q": 68.0, + "papr_db": 3.865460322480824, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.0038739127905273434 + } + }, + { + "label": "A2", + "symbol_rate": 20000, + "start": 5694272, + "samples": 1655200, + "active_start": 5702672, + "active_samples": 1638400, + "whole": { + "samples": 1655200, + "mean_i": -3.624939584340261e-06, + "mean_q": -8.458192363460609e-06, + "power_code2": 1936.3883820686322, + "ac_power_code2": 1936.3883820685476, + "rms_code": 44.00441321127498, + "peak_magnitude_code": 69.29646455628166, + "max_abs_i": 68.0, + "max_abs_q": 69.0, + "papr_db": 3.9442968742176006, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.09681941910343161 + }, + "active": { + "samples": 1638400, + "mean_i": 2.99072265625e-05, + "mean_q": -0.0008270263671875, + "power_code2": 1956.0524084472656, + "ac_power_code2": 1956.0524077623986, + "rms_code": 44.22728126900031, + "peak_magnitude_code": 69.29646455628166, + "max_abs_i": 68.0, + "max_abs_q": 69.0, + "papr_db": 3.9004166907590005, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.09780262042236328 + } + }, + { + "label": "B2", + "symbol_rate": 500000, + "start": 8149472, + "samples": 1639072, + "active_start": 8149808, + "active_samples": 1638400, + "whole": { + "samples": 1639072, + "mean_i": 0.00011042833993869702, + "mean_q": -0.002146336463559868, + "power_code2": 1936.1693793805275, + "ac_power_code2": 1936.169374761573, + "rms_code": 44.00192472359053, + "peak_magnitude_code": 68.6804193347711, + "max_abs_i": 66.0, + "max_abs_q": 68.0, + "papr_db": 3.8672252879366917, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.003872338758761055 + }, + "active": { + "samples": 1638400, + "mean_i": -8.544921875e-06, + "mean_q": -0.002210693359375, + "power_code2": 1936.9563952636718, + "ac_power_code2": 1936.9563903764335, + "rms_code": 44.010866786098084, + "peak_magnitude_code": 68.6804193347711, + "max_abs_i": 66.0, + "max_abs_q": 68.0, + "papr_db": 3.865460322480824, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.0038739127905273434 + } + } + ], + "whole_power_difference_db": -0.000491208472157679, + "active_power_difference_db": -0.0426064264748898 +} diff --git a/data/processed/lab056/rf_analysis.json b/data/processed/lab056/rf_analysis.json new file mode 100644 index 0000000..995f1ce --- /dev/null +++ b/data/processed/lab056/rf_analysis.json @@ -0,0 +1,530 @@ +{ + "scope": "TX_REFERENCE_DIAGNOSTICS_NOT_INDEPENDENT_PACKET_RX", + "rf_tx": 0, + "tx_sha256": "5b34bbe1a8e6d037d2d6d367a74e9eb84e8940db7da61600ffaa7f7497d4f600", + "rx_sha256": "e336dd653fa554058052fcf851e9f2462f66b8cf7c710815ca2b9a09ffc23ad4", + "alignment": { + "start": 4454784, + "correlation": 0.3843661479500724, + "coarse_cfo_hz": 0.0, + "stride": 32 + }, + "segments": [ + { + "label": "A1", + "symbol_rate": 20000, + "raw_rx": { + "samples": 1638400, + "mean_i": 0.9375872802734375, + "mean_q": 1.827298583984375, + "power_code2": 5.303053588867187, + "ac_power_code2": 1.084963565705345, + "rms_code": 2.3028359882690705, + "peak_magnitude_code": 6.4031242374328485, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 8.88257840909542, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.0002651526794433594, + "band_27000_power": 0.3472643231791639, + "band_675000_power": 0.5082992616247881, + "power_standard_error": 0.020810438717554197 + }, + "local_zero_iq_background_windows": [ + { + "samples": 480000, + "mean_i": 0.9454104166666667, + "mean_q": 1.8225354166666667, + "power_code2": 4.857945833333333, + "ac_power_code2": 0.642509632387152, + "rms_code": 2.204074824803671, + "peak_magnitude_code": 5.385164807134504, + "max_abs_i": 5.0, + "max_abs_q": 5.0, + "papr_db": 7.759453298373341, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.00024289729166666665, + "band_27000_power": 0.011441788935577513, + "band_675000_power": 0.1346566488652154, + "power_standard_error": 0.011146582753825698 + }, + { + "samples": 480000, + "mean_i": 0.9274020833333333, + "mean_q": 1.8395416666666666, + "power_code2": 4.84604375, + "ac_power_code2": 0.6020555824262157, + "rms_code": 2.2013731510127945, + "peak_magnitude_code": 5.0, + "max_abs_i": 3.0, + "max_abs_q": 4.0, + "papr_db": 7.125526780497051, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.0002423021875, + "band_27000_power": 0.009082996916230657, + "band_675000_power": 0.10440265872939565, + "power_standard_error": 0.005986244399660487 + } + ], + "background_power": 0.6222826074066838, + "background_subtracted_raw": 0.46268095829866107, + "background_subtracted_uncertainty": 0.029702310624809113, + "background_subtracted_stable": true, + "background_subtracted_signal_power": 0.46268095829866107, + "channel_gain_complex": { + "real": -0.008543898749645305, + "imag": 0.009310849226837265, + "phase_rad_at_active_start": 2.3132658926165255 + }, + "channel_gain_power": 0.0001596901191690867, + "measurement": { + "frame": 1, + "start": 5254791, + "alignment_adjustment": 7, + "rx_active": { + "samples": 1638400, + "mean_i": 0.9375872802734375, + "mean_q": 1.827298583984375, + "power_code2": 5.303053588867187, + "ac_power_code2": 1.084963565705345, + "rms_code": 2.3028359882690705, + "peak_magnitude_code": 6.4031242374328485, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 8.88257840909542, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.0002651526794433594 + }, + "cfo_hz": -0.028056675950692833, + "gain_abs": 0.012636855588677378, + "dc_i": 0.9388651889450522, + "dc_q": 1.8271201059862494, + "train_signal_power": 0.312403496916226, + "train_residual_power": 0.722356125700177, + "train_actual_ac_power": 1.0347596226164035, + "train_cross_power": 7.854827899222983e-17, + "heldout_signal_power": 0.31232098749561993, + "heldout_residual_power": 0.8215137283109276, + "heldout_actual_ac_power": 1.135170838604222, + "heldout_cross_power": 0.0013361227976749755, + "heldout_residual_band_27000_power": 0.03428707776367196, + "heldout_residual_band_675000_power": 0.18938129777540513, + "heldout_residual_band_1000000_power": 0.21334080727941662, + "heldout_residual_matched_power": 11.421082264513538, + "effective_signal_to_residual_db": -4.200136561843322 + } + }, + { + "label": "B1", + "symbol_rate": 500000, + "raw_rx": { + "samples": 1638400, + "mean_i": 0.9203680419921875, + "mean_q": 1.8407562255859375, + "power_code2": 5.328170166015625, + "ac_power_code2": 1.0927093512617043, + "rms_code": 2.30828294756419, + "peak_magnitude_code": 6.708203932499369, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 9.266344273087686, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.0656340332031251e-05, + "band_27000_power": 0.029697349664473127, + "band_675000_power": 0.5128322432606733, + "power_standard_error": 0.031085529715571047 + }, + "local_zero_iq_background_windows": [ + { + "samples": 480000, + "mean_i": 0.9274020833333333, + "mean_q": 1.8395416666666666, + "power_code2": 4.84604375, + "ac_power_code2": 0.6020555824262157, + "rms_code": 2.2013731510127945, + "peak_magnitude_code": 5.0, + "max_abs_i": 3.0, + "max_abs_q": 4.0, + "papr_db": 7.125526780497051, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 9.692087499999999e-06, + "band_27000_power": 0.009082996916230657, + "band_675000_power": 0.10440265872939565, + "power_standard_error": 0.005986244399660487 + }, + { + "samples": 480000, + "mean_i": 0.9213041666666667, + "mean_q": 1.8316708333333334, + "power_code2": 4.8351625, + "ac_power_code2": 0.6313430907986115, + "rms_code": 2.198900293328463, + "peak_magnitude_code": 5.0990195135927845, + "max_abs_i": 3.0, + "max_abs_q": 5.0, + "papr_db": 7.3056227355026895, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 9.670325e-06, + "band_27000_power": 0.011430099601181243, + "band_675000_power": 0.13125486016140642, + "power_standard_error": 0.0037407319242408464 + } + ], + "background_power": 0.6166993366124136, + "background_subtracted_raw": 0.4760100146492907, + "background_subtracted_uncertainty": 0.03454282477879906, + "background_subtracted_stable": true, + "background_subtracted_signal_power": 0.4760100146492907, + "channel_gain_complex": { + "real": -0.008089659584664989, + "imag": 0.009397483555426113, + "phase_rad_at_active_start": 2.2815457153366783 + }, + "channel_gain_power": 0.00015375528937026635, + "measurement": { + "frame": 1, + "start": 7709991, + "alignment_adjustment": 7, + "rx_active": { + "samples": 1638400, + "mean_i": 0.9203680419921875, + "mean_q": 1.8407562255859375, + "power_code2": 5.328170166015625, + "ac_power_code2": 1.0927093512617043, + "rms_code": 2.30828294756419, + "peak_magnitude_code": 6.708203932499369, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 9.266344273087686, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.0656340332031251e-05 + }, + "cfo_hz": -0.0731458112990823, + "gain_abs": 0.012399810053797854, + "dc_i": 0.920656229639791, + "dc_q": 1.8411261312835556, + "train_signal_power": 0.2978190572101343, + "train_residual_power": 0.7068527315140937, + "train_actual_ac_power": 1.0046717887242282, + "train_cross_power": -6.682154829462661e-17, + "heldout_signal_power": 0.29781552489257346, + "heldout_residual_power": 0.884789710339823, + "heldout_actual_ac_power": 1.1807473535638735, + "heldout_cross_power": -0.001857881668523386, + "heldout_residual_band_27000_power": 0.015187641333986188, + "heldout_residual_band_675000_power": 0.217181000785572, + "heldout_residual_band_1000000_power": 0.24523520739571264, + "heldout_residual_matched_power": 3.0703433988460103, + "effective_signal_to_residual_db": -4.72892729922049 + } + }, + { + "label": "A2", + "symbol_rate": 20000, + "raw_rx": { + "samples": 1638400, + "mean_i": 0.9284002685546875, + "mean_q": 1.84388427734375, + "power_code2": 5.311703491210937, + "ac_power_code2": 1.0498672043230375, + "rms_code": 2.304713320829933, + "peak_magnitude_code": 5.830951894845301, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 8.062450931004047, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.0002655851745605469, + "band_27000_power": 0.33592297470769195, + "band_675000_power": 0.500120184644421, + "power_standard_error": 0.01600143643844262 + }, + "local_zero_iq_background_windows": [ + { + "samples": 480000, + "mean_i": 0.92130625, + "mean_q": 1.8316708333333334, + "power_code2": 4.83516875, + "ac_power_code2": 0.6313455020269103, + "rms_code": 2.198901714492942, + "peak_magnitude_code": 5.0990195135927845, + "max_abs_i": 3.0, + "max_abs_q": 5.0, + "papr_db": 7.30561712175391, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.0002417584375, + "band_27000_power": 0.011430090514699676, + "band_675000_power": 0.13125475431725353, + "power_standard_error": 0.0037385404799615833 + }, + { + "samples": 480000, + "mean_i": 0.9283375, + "mean_q": 1.8603020833333332, + "power_code2": 4.962772916666666, + "ac_power_code2": 0.6402385615060755, + "rms_code": 2.2277281963171958, + "peak_magnitude_code": 5.830951894845301, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 8.357545135545596, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.00024813864583333333, + "band_27000_power": 0.011660806052520012, + "band_675000_power": 0.13208548597324482, + "power_standard_error": 0.009340294961573032 + } + ], + "background_power": 0.6357920317664929, + "background_subtracted_raw": 0.4140751725565446, + "background_subtracted_uncertainty": 0.017352868452820306, + "background_subtracted_stable": true, + "background_subtracted_signal_power": 0.4140751725565446, + "channel_gain_complex": { + "real": -0.007000883443887156, + "imag": 0.010205712402071436, + "phase_rad_at_active_start": 2.172048716307076 + }, + "channel_gain_power": 0.000153168934628688, + "measurement": { + "frame": 1, + "start": 10149062, + "alignment_adjustment": 6, + "rx_active": { + "samples": 1638400, + "mean_i": 0.9284002685546875, + "mean_q": 1.84388427734375, + "power_code2": 5.311703491210937, + "ac_power_code2": 1.0498672043230375, + "rms_code": 2.304713320829933, + "peak_magnitude_code": 5.830951894845301, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 8.062450931004047, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.0002655851745605469 + }, + "cfo_hz": 0.005915202430533777, + "gain_abs": 0.012376143770524322, + "dc_i": 0.9271611521067152, + "dc_q": 1.8443065713552416, + "train_signal_power": 0.29964603349233376, + "train_residual_power": 0.7155398694209132, + "train_actual_ac_power": 1.0151859029132475, + "train_cross_power": 2.4270516152391507e-16, + "heldout_signal_power": 0.29956689346716014, + "heldout_residual_power": 0.7826844440402193, + "heldout_actual_ac_power": 1.084551933216437, + "heldout_cross_power": 0.002300595709057756, + "heldout_residual_band_27000_power": 0.03443073439045887, + "heldout_residual_band_675000_power": 0.19776523377923858, + "heldout_residual_band_1000000_power": 0.22176016276354857, + "heldout_residual_matched_power": 11.341896374078306, + "effective_signal_to_residual_db": -4.170928864706292 + } + }, + { + "label": "B2", + "symbol_rate": 500000, + "raw_rx": { + "samples": 1638400, + "mean_i": 0.9302490234375, + "mean_q": 1.854871826171875, + "power_code2": 5.396551513671875, + "ac_power_code2": 1.0906387765392669, + "rms_code": 2.3230478931076464, + "peak_magnitude_code": 6.4031242374328485, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 8.806675296737527, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.0793103027343752e-05, + "band_27000_power": 0.030437416621842406, + "band_675000_power": 0.5333148504916424, + "power_standard_error": 0.03318734421277559 + }, + "local_zero_iq_background_windows": [ + { + "samples": 480000, + "mean_i": 0.9283375, + "mean_q": 1.8603020833333332, + "power_code2": 4.962772916666666, + "ac_power_code2": 0.6402385615060755, + "rms_code": 2.2277281963171958, + "peak_magnitude_code": 5.830951894845301, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 8.357545135545596, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 9.925545833333333e-06, + "band_27000_power": 0.011660770674569443, + "band_675000_power": 0.13208533141133466, + "power_standard_error": 0.009339092140283283 + }, + { + "samples": 480000, + "mean_i": 0.9385041666666667, + "mean_q": 1.8505104166666666, + "power_code2": 5.000202083333333, + "ac_power_code2": 0.6950232102907972, + "rms_code": 2.236113164250265, + "peak_magnitude_code": 5.385164807134504, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 7.634104411823291, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.0000404166666666e-05, + "band_27000_power": 0.011507358850526561, + "band_675000_power": 0.12385207349410385, + "power_standard_error": 0.037784295029485354 + } + ], + "background_power": 0.6676308858984363, + "background_subtracted_raw": 0.42300789064083055, + "background_subtracted_uncertainty": 0.04722771590637799, + "background_subtracted_stable": true, + "background_subtracted_signal_power": 0.42300789064083055, + "channel_gain_complex": { + "real": -0.006710536973189343, + "imag": 0.010126447128417442, + "phase_rad_at_active_start": 2.1560299377113283 + }, + "channel_gain_power": 0.000147576237913175, + "measurement": { + "frame": 1, + "start": 12604263, + "alignment_adjustment": 7, + "rx_active": { + "samples": 1638400, + "mean_i": 0.9302490234375, + "mean_q": 1.854871826171875, + "power_code2": 5.396551513671875, + "ac_power_code2": 1.0906387765392669, + "rms_code": 2.3230478931076464, + "peak_magnitude_code": 6.4031242374328485, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 8.806675296737527, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.0793103027343752e-05 + }, + "cfo_hz": 0.0026425717900911143, + "gain_abs": 0.012148096061242479, + "dc_i": 0.9315836612485033, + "dc_q": 1.8553663362050554, + "train_signal_power": 0.28585043299602836, + "train_residual_power": 0.7245263851886631, + "train_actual_ac_power": 1.010376818184691, + "train_cross_power": -8.954642582992278e-17, + "heldout_signal_power": 0.2858470426337267, + "heldout_residual_power": 0.8807229722868642, + "heldout_actual_ac_power": 1.1709047864903603, + "heldout_cross_power": 0.004334771569769229, + "heldout_residual_band_27000_power": 0.018795072832326204, + "heldout_residual_band_675000_power": 0.3125053797217844, + "heldout_residual_band_1000000_power": 0.3566678823693195, + "heldout_residual_matched_power": 4.361909383453252, + "effective_signal_to_residual_db": -4.887056210122219 + } + } + ], + "pairs": [ + { + "pair": 1, + "received_power_difference_db": 0.1233446340794126, + "channel_gain_difference_db": -0.1644798001918496, + "matched_component_difference_db": -0.20653835698711864, + "matched_component_symbol_energy_difference_db": -14.185938443707496 + }, + { + "pair": 2, + "received_power_difference_db": 0.09269277113182464, + "channel_gain_difference_db": -0.16154256719796828, + "matched_component_difference_db": -0.2036011239932389, + "matched_component_symbol_energy_difference_db": -14.183001210713615 + } + ], + "comparison_summary": { + "repeatability": [ + { + "comparison": "A2/A1", + "raw_rx_power_difference_db": 0.007078081316567549, + "background_difference_db": 0.0932741793444109, + "received_power_difference_db": -0.4820243490149181, + "channel_gain_difference_db": -0.18107353366707263, + "matched_component_difference_db": -0.1810735336670716 + }, + { + "comparison": "B2/B1", + "raw_rx_power_difference_db": 0.055382405794076286, + "background_difference_db": 0.34462938523123676, + "received_power_difference_db": -0.5126762119625052, + "channel_gain_difference_db": -0.17813630067319114, + "matched_component_difference_db": -0.17813630067319214 + } + ], + "averaging": "RATIO_OF_MEAN_LINEAR_POWERS_B1_B2_OVER_A1_A2", + "received_power_difference_db": 0.10889530008758355, + "channel_gain_difference_db": -0.16304154709643187, + "energy_per_symbol_difference_db": -13.870504786632791, + "energy_basis": "BACKGROUND_SUBTRACTED_RECEIVED_POWER_DIVIDED_BY_SYMBOL_RATE" + }, + "outside_waveform_background": [ + { + "start": 3654784, + "samples": 400000, + "mean_i": 0.9425475, + "mean_q": 1.823755, + "power_code2": 4.8400925, + "ac_power_code2": 0.6256144102187502, + "rms_code": 2.2000210226268293, + "peak_magnitude_code": 5.0, + "max_abs_i": 3.0, + "max_abs_q": 4.0, + "papr_db": 7.1308634705743845, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.000242004625, + "band_27000_power": 0.011134411836977165, + "band_675000_power": 0.12535191126457693, + "power_standard_error": 0.002472279873801531 + }, + { + "start": 15443328, + "samples": 400000, + "mean_i": 0.938865, + "mean_q": 1.832065, + "power_code2": 4.891855, + "ac_power_code2": 0.6539253475500004, + "rms_code": 2.2117538289782614, + "peak_magnitude_code": 5.0, + "max_abs_i": 3.0, + "max_abs_q": 4.0, + "papr_db": 7.0846643308644, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.00024459275, + "band_27000_power": 0.012745444722198074, + "band_675000_power": 0.13232609430446385, + "power_standard_error": 0.008612381752597367 + } + ], + "background_note": "Внутренние gaps: нулевой цифровой IQ при работающем TX; это не RF OFF. Внешние окна также требуют сверки времён запуска/остановки по журналам.", + "power_units": "RX code squared, not calibrated watts/dBm", + "residual_note": "Шум и неописанные моделью искажения; RX не нормируется для выравнивания A/B" +} diff --git a/data/processed/lab056/rf_overview.png b/data/processed/lab056/rf_overview.png new file mode 100644 index 0000000000000000000000000000000000000000..be4d75c763d5c2973f381f52fec86bf3785e2633 GIT binary patch literal 310041 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

_rxuvn;4tqy`xW&2El&(#c)H-C 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 TX antenna -> free-space LOS -> RX antenna -> SLAVE RX; user-specified approximate distance 3-5 m; fixed equipment and cables", + "path_confirmed": true, + "tx_antenna": "Existing 1400 MHz antenna, as described by user; model/marking not supplied", + "rx_antenna": "Existing 1400 MHz antenna, as described by user; model/marking not supplied", + "distance_m": null, + "orientation": "Both stationary; same antenna orientation and polarization, per user", + "visibility": "LOS" + }, + "process_before": { + "state": "CLEAR", + "attempts": [ + { + "state": "CLEAR", + "mechanism": "psutil", + "matches": [], + "inspected": 302, + "errors": [] + } + ] + }, + "inventory": { + "passed": true, + "serials": [ + "000000000000000097c063dc2e5327d3", + "000000000000000097c063dc323b97d3" + ], + "master_serial": "000000000000000097c063dc323b97d3", + "slave_serial": "000000000000000097c063dc2e5327d3", + "raw_output": "hackrf_info version: 2024.02.1\nlibhackrf version: 2024.02.1 (0.9)\nFound HackRF\nIndex: 0\nSerial number: 000000000000000097c063dc323b97d3\nBoard ID Number: 4 (HackRF One)\nFirmware Version: 2024.02.1 (API:1.08)\nPart ID Number: 0xa000cb3c 0x00744f5a\nHardware Revision: r9\nHardware does not appear to have been manufactured by Great Scott Gadgets.\nHardware supported by installed firmware:\n HackRF One\n\nFound HackRF\nIndex: 1\nSerial number: 000000000000000097c063dc2e5327d3\nBoard ID Number: 4 (HackRF One)\nFirmware Version: 2024.02.1 (API:1.08)\nPart ID Number: 0xa000cb3c 0xbc4b4739\nHardware Revision: r9\nHardware does not appear to have been manufactured by Great Scott Gadgets.\nHardware supported by installed firmware:\n HackRF One" + }, + "clock": { + "passed": true, + "master_reg29": 38, + "slave_reg29": 38, + "slave_clkin_status": "DETECTED", + "slave_clock_wait": { + "state": "DETECTED", + "queries": 2, + "time_to_detect_ms": 137.35900004394352, + "elapsed_ms": 137.35900004394352, + "polls": [ + { + "query": 1, + "start_ms": 50.7242000894621, + "end_ms": 69.19760000891984, + "raw": "CLKIN status: no clock signal detected", + "state": "NOT_DETECTED", + "exit_code": 0 + }, + { + "query": 2, + "start_ms": 119.4211000110954, + "end_ms": 137.35900004394352, + "raw": "CLKIN status: clock signal detected", + "state": "DETECTED", + "exit_code": 0 + } + ] + }, + "master_serial": "000000000000000097c063dc323b97d3", + "slave_serial": "000000000000000097c063dc2e5327d3" + }, + "rx_level_before_tx": { + "samples": 65536, + "mean_i": 0.938690185546875, + "mean_q": 1.825347900390625, + "power_code2": 4.84039306640625, + "ac_power_code2": 0.6273588445037603, + "rms_code": 2.2000893314604864, + "peak_magnitude_code": 4.47213595499958, + "max_abs_i": 3.0, + "max_abs_q": 4.0, + "papr_db": 6.161493654989252, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.0002420196533203125, + "saturation_detected": false, + "analog_compression": "UNKNOWN_WITHOUT_CALIBRATION" + }, + "rx_sha256": "e336dd653fa554058052fcf851e9f2462f66b8cf7c710815ca2b9a09ffc23ad4", + "rx_level": { + "samples": 24000000, + "mean_i": 0.9305354583333333, + "mean_q": 1.8321060833333334, + "power_code2": 4.996925875, + "ac_power_code2": 0.7744169351973671, + "rms_code": 2.235380476563218, + "peak_magnitude_code": 6.708203932499369, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 9.545096066616024, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.00024984629375, + "saturation_detected": false, + "analog_compression": "UNKNOWN_WITHOUT_CALIBRATION" + }, + "process_after": { + "state": "CLEAR", + "attempts": [ + { + "state": "CLEAR", + "mechanism": "psutil", + "matches": [], + "inspected": 302, + "errors": [] + } + ] + }, + "cleanup_errors": [] + }, + "rx_bytes": 48000000, + "rx_samples": 24000000, + "rx_seconds": 3.0, + "tx_bytes": 21177088, + "tx_samples": 10588544, + "tx_waveform_seconds": 1.323568, + "rx_overruns": 0, + "tx_underruns": 0, + "rx_clipped_samples": 0, + "rx_clipped_components": 0, + "all_four_segments_present": true, + "segmentation_start_spread_samples": 1, + "hardware_parameters_constant_between_segments": true, + "physical_geometry_source": "USER_DESCRIPTION_NOT_SOFTWARE_MEASUREMENT", + "audited_hardware_commands": 14, + "audited_tx_commands": 1, + "segments": [ + { + "label": "A1", + "start_sample": 5254791, + "end_sample_exclusive": 6909991, + "start_seconds": 0.656848875, + "end_seconds": 0.863748875, + "inferred_sequence_start_sample": 4454791, + "active_samples": 1638400, + "raw_rx_power_code2": 5.303053588867187, + "rx_ac_power_code2": 1.084963565705345, + "background_power_code2": 0.6222826074066838, + "background_subtracted_signal_power_code2": 0.46268095829866107, + "background_subtracted_uncertainty_code2": 0.029702310624809113, + "background_subtracted_stable": true, + "complex_gain_h": { + "real": -0.008543898749645305, + "imag": 0.009310849226837265, + "phase_rad_at_active_start": 2.3132658926165255 + }, + "channel_gain_power": 0.0001596901191690867, + "matched_signal_component_power_code2": 0.31232098749561993, + "residual_power_code2": 0.8215137283109276, + "spectral_band_27000_power_code2": 0.3472643231791639, + "spectral_band_675000_power_code2": 0.5082992616247881 + }, + { + "label": "B1", + "start_sample": 7709991, + "end_sample_exclusive": 9349063, + "start_seconds": 0.963748875, + "end_seconds": 1.168632875, + "inferred_sequence_start_sample": 4454791, + "active_samples": 1638400, + "raw_rx_power_code2": 5.328170166015625, + "rx_ac_power_code2": 1.0927093512617043, + "background_power_code2": 0.6166993366124136, + "background_subtracted_signal_power_code2": 0.4760100146492907, + "background_subtracted_uncertainty_code2": 0.03454282477879906, + "background_subtracted_stable": true, + "complex_gain_h": { + "real": -0.008089659584664989, + "imag": 0.009397483555426113, + "phase_rad_at_active_start": 2.2815457153366783 + }, + "channel_gain_power": 0.00015375528937026635, + "matched_signal_component_power_code2": 0.29781552489257346, + "residual_power_code2": 0.884789710339823, + "spectral_band_27000_power_code2": 0.029697349664473127, + "spectral_band_675000_power_code2": 0.5128322432606733 + }, + { + "label": "A2", + "start_sample": 10149062, + "end_sample_exclusive": 11804262, + "start_seconds": 1.26863275, + "end_seconds": 1.47553275, + "inferred_sequence_start_sample": 4454790, + "active_samples": 1638400, + "raw_rx_power_code2": 5.311703491210937, + "rx_ac_power_code2": 1.0498672043230375, + "background_power_code2": 0.6357920317664929, + "background_subtracted_signal_power_code2": 0.4140751725565446, + "background_subtracted_uncertainty_code2": 0.017352868452820306, + "background_subtracted_stable": true, + "complex_gain_h": { + "real": -0.007000883443887156, + "imag": 0.010205712402071436, + "phase_rad_at_active_start": 2.172048716307076 + }, + "channel_gain_power": 0.000153168934628688, + "matched_signal_component_power_code2": 0.29956689346716014, + "residual_power_code2": 0.7826844440402193, + "spectral_band_27000_power_code2": 0.33592297470769195, + "spectral_band_675000_power_code2": 0.500120184644421 + }, + { + "label": "B2", + "start_sample": 12604263, + "end_sample_exclusive": 14243335, + "start_seconds": 1.575532875, + "end_seconds": 1.780416875, + "inferred_sequence_start_sample": 4454791, + "active_samples": 1638400, + "raw_rx_power_code2": 5.396551513671875, + "rx_ac_power_code2": 1.0906387765392669, + "background_power_code2": 0.6676308858984363, + "background_subtracted_signal_power_code2": 0.42300789064083055, + "background_subtracted_uncertainty_code2": 0.04722771590637799, + "background_subtracted_stable": true, + "complex_gain_h": { + "real": -0.006710536973189343, + "imag": 0.010126447128417442, + "phase_rad_at_active_start": 2.1560299377113283 + }, + "channel_gain_power": 0.000147576237913175, + "matched_signal_component_power_code2": 0.2858470426337267, + "residual_power_code2": 0.8807229722868642, + "spectral_band_27000_power_code2": 0.030437416621842406, + "spectral_band_675000_power_code2": 0.5333148504916424 + } + ], + "comparison_summary": { + "repeatability": [ + { + "comparison": "A2/A1", + "raw_rx_power_difference_db": 0.007078081316567549, + "background_difference_db": 0.0932741793444109, + "received_power_difference_db": -0.4820243490149181, + "channel_gain_difference_db": -0.18107353366707263, + "matched_component_difference_db": -0.1810735336670716 + }, + { + "comparison": "B2/B1", + "raw_rx_power_difference_db": 0.055382405794076286, + "background_difference_db": 0.34462938523123676, + "received_power_difference_db": -0.5126762119625052, + "channel_gain_difference_db": -0.17813630067319114, + "matched_component_difference_db": -0.17813630067319214 + } + ], + "averaging": "RATIO_OF_MEAN_LINEAR_POWERS_B1_B2_OVER_A1_A2", + "received_power_difference_db": 0.10889530008758355, + "channel_gain_difference_db": -0.16304154709643187, + "energy_per_symbol_difference_db": -13.870504786632791, + "energy_basis": "BACKGROUND_SUBTRACTED_RECEIVED_POWER_DIVIDED_BY_SYMBOL_RATE" + }, + "pairs": [ + { + "pair": 1, + "received_power_difference_db": 0.1233446340794126, + "channel_gain_difference_db": -0.1644798001918496, + "matched_component_difference_db": -0.20653835698711864, + "matched_component_symbol_energy_difference_db": -14.185938443707496 + }, + { + "pair": 2, + "received_power_difference_db": 0.09269277113182464, + "channel_gain_difference_db": -0.16154256719796828, + "matched_component_difference_db": -0.2036011239932389, + "matched_component_symbol_energy_difference_db": -14.183001210713615 + } + ], + "energy_basis": "BACKGROUND_SUBTRACTED_RECEIVED_POWER_DIVIDED_BY_SYMBOL_RATE", + "units": "RX_CODE_SQUARED_AND_CODE_SQUARED_SECONDS_NOT_CALIBRATED_WATTS_OR_JOULES", + "interpretation": { + "historical_15_41_db_drop_reproduced": false, + "isolated_hackrf_loss_established": false, + "scope": "ENTIRE_OTA_PATH_IN_THIS_SESSION", + "conducted_control_required_to_separate_hardware_and_channel": true, + "external_amplifier_necessity_established": false, + "packet_acceptance_tested": false + }, + "verifier": { + "passed": true, + "mode": "SAVED_FILES_READ_ONLY_NO_HARDWARE", + "independent_methods": [ + "INTEGER_RAW_MOMENTS", + "LOCAL_VARIANCE", + "WEIGHTED_PHASE_CFO", + "COMPLEX_LSTSQ" + ], + "remaining_reproduced_findings": 0 + }, + "lab054_official": "NOT_A, 0/16", + "lab055_inputs_unchanged": 34, + "last_software_tests_same_code": { + "targeted": 44, + "pytest": 867, + "quick_gate": [ + 867, + 30, + 13 + ] + }, + "code_or_tx_changed": false, + "head": "5add95ecb8865f59075bbbced08d97b183fb3b48", + "lab056_committed": false, + "push": false, + "stop": true, + "artifact_sha256": { + "data/raw/lab056/tx_abab.cs8": "5b34bbe1a8e6d037d2d6d367a74e9eb84e8940db7da61600ffaa7f7497d4f600", + "data/raw/lab056/tx_metadata.json": "535375d08a0699ac4be31992ddbb6c5d175b3156a0a3b508b45d7cb567c24071", + "data/raw/lab056/rx_stream.cs8": "e336dd653fa554058052fcf851e9f2462f66b8cf7c710815ca2b9a09ffc23ad4", + "data/raw/lab056/hardware_attempt.json": "24dfed564a260c6286233a21823cf13f5d19731adaa5bf6664debeddde634ffd", + "data/raw/lab056/capture_result.json": "107ff5b43cd98acbb6ea77631894a1ff2fcb95868702f2dafa73675b69a16bdd", + "data/raw/lab056/tx_process_result.json": "88e13edd733430b2a42dd176ff275f518be39e1733da6b904a03493b99354475", + "data/raw/lab056/rx_stdout.txt": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "data/raw/lab056/rx_stderr.txt": "3b0c3dc749f353bad62f36b198745d9dd2850372ad2a0450ae645afad300361a", + "data/processed/lab056/rf_analysis.json": "21576f57910458a3fbe0090894a6ba61540b8a1a08094fca16cd06c46058d141", + "data/processed/lab056/rf_session_authorization.json": "52bf979934c2c27bee055b07e09685248d411a48b79f49b6f000b5e2c631e0c1", + "data/processed/lab056/rf_session_commands.json": "c816829a57f8613c29fa228ce1a03b93df79997e619d8dfaa827186c7820171b", + "data/processed/lab056/rf_overview.png": "c08a8dab99677afb46b0cc43dbf2360da47da35a03dc00fdec48618c7c794f4f", + "experiments/lab056_capture_runner.py": "24c17060b8b3e3f6899f9e922ae818e7ae2efba456c5f5cada7c69b5e5429334", + "experiments/lab056_abab_energy.py": "323408b3bc1aa02c8b2f2855cd6295ac2efd99f13afec2ca0c872aa013a78f96" + } +} diff --git a/data/processed/lab056/rf_session_authorization.json b/data/processed/lab056/rf_session_authorization.json new file mode 100644 index 0000000..4cf58cb --- /dev/null +++ b/data/processed/lab056/rf_session_authorization.json @@ -0,0 +1,30 @@ +{ + "authorized_tx_sessions": 1, + "automatic_retry": false, + "point": { + "frequency_hz": 1400000000, + "physical_path": "MASTER TX -> TX antenna -> free-space LOS -> RX antenna -> SLAVE RX; user-specified approximate distance 3-5 m; fixed equipment and cables", + "path_confirmed": true, + "tx_antenna": "Existing 1400 MHz antenna, as described by user; model/marking not supplied", + "rx_antenna": "Existing 1400 MHz antenna, as described by user; model/marking not supplied", + "distance_m": null, + "orientation": "Both stationary; same antenna orientation and polarization, per user", + "visibility": "LOS" + }, + "tx_sha256": "5b34bbe1a8e6d037d2d6d367a74e9eb84e8940db7da61600ffaa7f7497d4f600", + "tx_samples": 10588544, + "tx_seconds": 1.323568, + "rx_samples": 24000000, + "rx_seconds": 3.0, + "tx_gain_db": 10, + "rx_gain_db": [ + 24, + 24 + ], + "amp": false, + "bias_tee": false, + "sample_rate_hz": 8000000, + "digital_carrier_hz": 50000, + "source": "Explicit user authorization in current turn", + "recorded_at_utc": "2026-09-10T09:32:24.185185+00:00" +} diff --git a/data/processed/lab056/rf_session_commands.json b/data/processed/lab056/rf_session_commands.json new file mode 100644 index 0000000..07ac902 --- /dev/null +++ b/data/processed/lab056/rf_session_commands.json @@ -0,0 +1,262 @@ +{ + "tx_process_invocations": 1, + "automatic_retry": false, + "commands": [ + { + "command": [ + "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_info.exe" + ], + "started_at_utc": "2026-09-10T09:32:24.697133+00:00", + "returncode": 0, + "stdout": "hackrf_info version: 2024.02.1\nlibhackrf version: 2024.02.1 (0.9)\nFound HackRF\nIndex: 0\nSerial number: 000000000000000097c063dc323b97d3\nBoard ID Number: 4 (HackRF One)\nFirmware Version: 2024.02.1 (API:1.08)\nPart ID Number: 0xa000cb3c 0x00744f5a\nHardware Revision: r9\nHardware does not appear to have been manufactured by Great Scott Gadgets.\nHardware supported by installed firmware:\n HackRF One\n\nFound HackRF\nIndex: 1\nSerial number: 000000000000000097c063dc2e5327d3\nBoard ID Number: 4 (HackRF One)\nFirmware Version: 2024.02.1 (API:1.08)\nPart ID Number: 0xa000cb3c 0xbc4b4739\nHardware Revision: r9\nHardware does not appear to have been manufactured by Great Scott Gadgets.\nHardware supported by installed firmware:\n HackRF One\n", + "stderr": "", + "finished_at_utc": "2026-09-10T09:32:24.719605+00:00" + }, + { + "command": [ + "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_clock.exe", + "-d", + "000000000000000097c063dc323b97d3", + "-o", + "0" + ], + "started_at_utc": "2026-09-10T09:32:24.719707+00:00", + "returncode": 0, + "stdout": "", + "stderr": "", + "finished_at_utc": "2026-09-10T09:32:24.736985+00:00" + }, + { + "command": [ + "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_clock.exe", + "-d", + "000000000000000097c063dc2e5327d3", + "-o", + "0" + ], + "started_at_utc": "2026-09-10T09:32:24.737066+00:00", + "returncode": 0, + "stdout": "", + "stderr": "", + "finished_at_utc": "2026-09-10T09:32:24.753370+00:00" + }, + { + "command": [ + "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_transfer.exe", + "-d", + "000000000000000097c063dc323b97d3", + "-r", + "NUL", + "-f", + "1400000000", + "-s", + "8000000", + "-n", + "65536", + "-l", + "24", + "-g", + "24", + "-a", + "0", + "-p", + "0", + "-B" + ], + "started_at_utc": "2026-09-10T09:32:24.753426+00:00", + "returncode": 0, + "stdout": "", + "stderr": "call hackrf_set_sample_rate(8000000 Hz/8.000 MHz)\ncall hackrf_set_hw_sync_mode(0)\ncall hackrf_set_freq(1400000000 Hz/1400.000 MHz)\ncall hackrf_set_amp_enable(0)\ncall hackrf_set_antenna_enable(0)\nsamples_to_xfer 65536/0Mio\nStop with Ctrl-C\n 0.3 MiB / 0.018 sec = 14.8 MiB/second, average power -29.9 dBfs, 9376 bytes free in buffer, 0 overruns, longest 0 bytes\n\nExiting...\nTotal time: 0.01795 s\nhackrf_stop_rx() done\nTransfer statistics:\n274144 bytes transferred by M0\n262144 bytes transferred by M4\n0 overruns, longest 0 bytes\nhackrf_close() done\nhackrf_exit() done\nfclose() done\nexit\n", + "finished_at_utc": "2026-09-10T09:32:24.790201+00:00" + }, + { + "command": [ + "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_debug.exe", + "-d", + "000000000000000097c063dc323b97d3", + "--si5351c", + "-n", + "29", + "-r" + ], + "started_at_utc": "2026-09-10T09:32:24.790253+00:00", + "returncode": 0, + "stdout": "[ 29] -> 0x26\n", + "stderr": "", + "finished_at_utc": "2026-09-10T09:32:24.807254+00:00" + }, + { + "command": [ + "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_clock.exe", + "-d", + "000000000000000097c063dc323b97d3", + "-o", + "1" + ], + "started_at_utc": "2026-09-10T09:32:24.807310+00:00", + "returncode": 0, + "stdout": "", + "stderr": "", + "finished_at_utc": "2026-09-10T09:32:24.823113+00:00" + }, + { + "command": [ + "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_clock.exe", + "-d", + "000000000000000097c063dc2e5327d3", + "-i" + ], + "started_at_utc": "2026-09-10T09:32:24.858007+00:00", + "returncode": 0, + "stdout": "CLKIN status: no clock signal detected\n", + "stderr": "", + "finished_at_utc": "2026-09-10T09:32:24.876412+00:00" + }, + { + "command": [ + "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_clock.exe", + "-d", + "000000000000000097c063dc2e5327d3", + "-i" + ], + "started_at_utc": "2026-09-10T09:32:24.926726+00:00", + "returncode": 0, + "stdout": "CLKIN status: clock signal detected\n", + "stderr": "", + "finished_at_utc": "2026-09-10T09:32:24.944618+00:00" + }, + { + "command": [ + "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_transfer.exe", + "-d", + "000000000000000097c063dc2e5327d3", + "-r", + "NUL", + "-f", + "1400000000", + "-s", + "8000000", + "-n", + "65536", + "-l", + "24", + "-g", + "24", + "-a", + "0", + "-p", + "0", + "-B" + ], + "started_at_utc": "2026-09-10T09:32:24.944681+00:00", + "returncode": 0, + "stdout": "", + "stderr": "call hackrf_set_sample_rate(8000000 Hz/8.000 MHz)\ncall hackrf_set_hw_sync_mode(0)\ncall hackrf_set_freq(1400000000 Hz/1400.000 MHz)\ncall hackrf_set_amp_enable(0)\ncall hackrf_set_antenna_enable(0)\nsamples_to_xfer 65536/0Mio\nStop with Ctrl-C\n 0.3 MiB / 0.017 sec = 15.4 MiB/second, average power -35.4 dBfs, 8832 bytes free in buffer, 0 overruns, longest 0 bytes\n\nExiting...\nTotal time: 0.01704 s\nhackrf_stop_rx() done\nTransfer statistics:\n274976 bytes transferred by M0\n262144 bytes transferred by M4\n0 overruns, longest 0 bytes\nhackrf_close() done\nhackrf_exit() done\nfclose() done\nexit\n", + "finished_at_utc": "2026-09-10T09:32:24.979112+00:00" + }, + { + "command": [ + "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_debug.exe", + "-d", + "000000000000000097c063dc2e5327d3", + "--si5351c", + "-n", + "29", + "-r" + ], + "started_at_utc": "2026-09-10T09:32:24.979161+00:00", + "returncode": 0, + "stdout": "[ 29] -> 0x26\n", + "stderr": "", + "finished_at_utc": "2026-09-10T09:32:24.995463+00:00" + }, + { + "command": [ + "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_transfer.exe", + "-d", + "000000000000000097c063dc2e5327d3", + "-r", + "C:\\Users\\user\\Desktop\\projects\\SDR_Rover\\data\\raw\\lab056\\rx_stream.cs8", + "-f", + "1400000000", + "-s", + "8000000", + "-n", + "24000000", + "-l", + "24", + "-g", + "24", + "-a", + "0", + "-p", + "0", + "-B" + ], + "started_at_utc": "2026-09-10T09:32:24.995551+00:00", + "background_process": true, + "stdout_path": "C:\\Users\\user\\Desktop\\projects\\SDR_Rover\\data\\raw\\lab056\\rx_stdout.txt", + "stderr_path": "C:\\Users\\user\\Desktop\\projects\\SDR_Rover\\data\\raw\\lab056\\rx_stderr.txt", + "returncode": 0, + "finished_at_utc": "2026-09-10T09:32:28.029923+00:00", + "returncode_after_cleanup": 0, + "cleanup_at_utc": "2026-09-10T09:32:28.683438+00:00" + }, + { + "command": [ + "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_transfer.exe", + "-d", + "000000000000000097c063dc323b97d3", + "-t", + "C:\\Users\\user\\Desktop\\projects\\SDR_Rover\\data\\raw\\lab056\\tx_abab.cs8", + "-f", + "1400000000", + "-s", + "8000000", + "-n", + "10588544", + "-x", + "10", + "-a", + "0", + "-p", + "0", + "-B" + ], + "started_at_utc": "2026-09-10T09:32:25.512893+00:00", + "returncode": 0, + "stdout": "", + "stderr": "call hackrf_set_sample_rate(8000000 Hz/8.000 MHz)\ncall hackrf_set_hw_sync_mode(0)\ncall hackrf_set_freq(1400000000 Hz/1400.000 MHz)\ncall hackrf_set_amp_enable(0)\ncall hackrf_set_antenna_enable(0)\nsamples_to_xfer 10588544/10Mio\nStop with Ctrl-C\n16.0 MiB / 1.004 sec = 15.9 MiB/second, average power -11.3 dBfs, 13920 bytes filled in buffer, 0 underruns, longest 0 bytes\n 5.2 MiB / 0.322 sec = 16.1 MiB/second, average power -11.2 dBfs, 5120 bytes filled in buffer, 0 underruns, longest 0 bytes\n\nExiting...\nTotal time: 1.32538 s\nhackrf_stop_tx() done\nTransfer statistics:\n21200896 bytes transferred by M0\n21200896 bytes transferred by M4\n0 underruns, longest 0 bytes\nhackrf_close() done\nhackrf_exit() done\nfclose() done\nexit\n", + "finished_at_utc": "2026-09-10T09:32:26.901844+00:00" + }, + { + "command": [ + "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_clock.exe", + "-d", + "000000000000000097c063dc323b97d3", + "-o", + "0" + ], + "started_at_utc": "2026-09-10T09:32:28.683494+00:00", + "returncode": 0, + "stdout": "", + "stderr": "", + "finished_at_utc": "2026-09-10T09:32:28.698845+00:00" + }, + { + "command": [ + "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_clock.exe", + "-d", + "000000000000000097c063dc2e5327d3", + "-o", + "0" + ], + "started_at_utc": "2026-09-10T09:32:28.698895+00:00", + "returncode": 0, + "stdout": "", + "stderr": "", + "finished_at_utc": "2026-09-10T09:32:28.714042+00:00" + } + ], + "orchestration_finished_at_utc": "2026-09-10T09:32:29.203758+00:00" +} diff --git a/data/processed/lab056/rx_preflight_commands.json b/data/processed/lab056/rx_preflight_commands.json new file mode 100644 index 0000000..782e0f8 --- /dev/null +++ b/data/processed/lab056/rx_preflight_commands.json @@ -0,0 +1,218 @@ +{ + "rf_tx_count": 0, + "tx_commands": 0, + "commands": [ + { + "command": [ + "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_info.exe" + ], + "started_at_utc": "2026-09-10T09:16:28.777578+00:00", + "returncode": 0, + "stdout": "hackrf_info version: 2024.02.1\nlibhackrf version: 2024.02.1 (0.9)\nFound HackRF\nIndex: 0\nSerial number: 000000000000000097c063dc323b97d3\nBoard ID Number: 4 (HackRF One)\nFirmware Version: 2024.02.1 (API:1.08)\nPart ID Number: 0xa000cb3c 0x00744f5a\nHardware Revision: r9\nHardware does not appear to have been manufactured by Great Scott Gadgets.\nHardware supported by installed firmware:\n HackRF One\n\nFound HackRF\nIndex: 1\nSerial number: 000000000000000097c063dc2e5327d3\nBoard ID Number: 4 (HackRF One)\nFirmware Version: 2024.02.1 (API:1.08)\nPart ID Number: 0xa000cb3c 0xbc4b4739\nHardware Revision: r9\nHardware does not appear to have been manufactured by Great Scott Gadgets.\nHardware supported by installed firmware:\n HackRF One\n", + "stderr": "", + "finished_at_utc": "2026-09-10T09:16:28.849704+00:00" + }, + { + "command": [ + "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_clock.exe", + "-d", + "000000000000000097c063dc323b97d3", + "-o", + "0" + ], + "started_at_utc": "2026-09-10T09:16:28.849843+00:00", + "returncode": 0, + "stdout": "", + "stderr": "", + "finished_at_utc": "2026-09-10T09:16:28.881216+00:00" + }, + { + "command": [ + "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_clock.exe", + "-d", + "000000000000000097c063dc2e5327d3", + "-o", + "0" + ], + "started_at_utc": "2026-09-10T09:16:28.881271+00:00", + "returncode": 0, + "stdout": "", + "stderr": "", + "finished_at_utc": "2026-09-10T09:16:28.899025+00:00" + }, + { + "command": [ + "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_transfer.exe", + "-d", + "000000000000000097c063dc323b97d3", + "-r", + "NUL", + "-f", + "1400000000", + "-s", + "8000000", + "-n", + "65536", + "-l", + "24", + "-g", + "24", + "-a", + "0", + "-p", + "0", + "-B" + ], + "started_at_utc": "2026-09-10T09:16:28.899092+00:00", + "returncode": 0, + "stdout": "", + "stderr": "call hackrf_set_sample_rate(8000000 Hz/8.000 MHz)\ncall hackrf_set_hw_sync_mode(0)\ncall hackrf_set_freq(1400000000 Hz/1400.000 MHz)\ncall hackrf_set_amp_enable(0)\ncall hackrf_set_antenna_enable(0)\nsamples_to_xfer 65536/0Mio\nStop with Ctrl-C\n 0.3 MiB / 0.019 sec = 13.5 MiB/second, average power -27.9 dBfs, 9280 bytes free in buffer, 0 overruns, longest 0 bytes\n\nExiting...\nTotal time: 0.01979 s\nhackrf_stop_rx() done\nTransfer statistics:\n276256 bytes transferred by M0\n262144 bytes transferred by M4\n0 overruns, longest 0 bytes\nhackrf_close() done\nhackrf_exit() done\nfclose() done\nexit\n", + "finished_at_utc": "2026-09-10T09:16:28.950743+00:00" + }, + { + "command": [ + "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_debug.exe", + "-d", + "000000000000000097c063dc323b97d3", + "--si5351c", + "-n", + "29", + "-r" + ], + "started_at_utc": "2026-09-10T09:16:28.950806+00:00", + "returncode": 0, + "stdout": "[ 29] -> 0x26\n", + "stderr": "", + "finished_at_utc": "2026-09-10T09:16:28.980731+00:00" + }, + { + "command": [ + "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_clock.exe", + "-d", + "000000000000000097c063dc323b97d3", + "-o", + "1" + ], + "started_at_utc": "2026-09-10T09:16:28.980796+00:00", + "returncode": 0, + "stdout": "", + "stderr": "", + "finished_at_utc": "2026-09-10T09:16:28.996692+00:00" + }, + { + "command": [ + "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_clock.exe", + "-d", + "000000000000000097c063dc2e5327d3", + "-i" + ], + "started_at_utc": "2026-09-10T09:16:29.030946+00:00", + "returncode": 0, + "stdout": "CLKIN status: clock signal detected\n", + "stderr": "", + "finished_at_utc": "2026-09-10T09:16:29.048522+00:00" + }, + { + "command": [ + "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_transfer.exe", + "-d", + "000000000000000097c063dc2e5327d3", + "-r", + "NUL", + "-f", + "1400000000", + "-s", + "8000000", + "-n", + "65536", + "-l", + "24", + "-g", + "24", + "-a", + "0", + "-p", + "0", + "-B" + ], + "started_at_utc": "2026-09-10T09:16:29.048596+00:00", + "returncode": 0, + "stdout": "", + "stderr": "call hackrf_set_sample_rate(8000000 Hz/8.000 MHz)\ncall hackrf_set_hw_sync_mode(0)\ncall hackrf_set_freq(1400000000 Hz/1400.000 MHz)\ncall hackrf_set_amp_enable(0)\ncall hackrf_set_antenna_enable(0)\nsamples_to_xfer 65536/0Mio\nStop with Ctrl-C\n 0.3 MiB / 0.019 sec = 14.0 MiB/second, average power -32.0 dBfs, 9120 bytes free in buffer, 0 overruns, longest 0 bytes\n\nExiting...\nTotal time: 0.01894 s\nhackrf_stop_rx() done\nTransfer statistics:\n273920 bytes transferred by M0\n262144 bytes transferred by M4\n0 overruns, longest 0 bytes\nhackrf_close() done\nhackrf_exit() done\nfclose() done\nexit\n", + "finished_at_utc": "2026-09-10T09:16:29.084743+00:00" + }, + { + "command": [ + "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_debug.exe", + "-d", + "000000000000000097c063dc2e5327d3", + "--si5351c", + "-n", + "29", + "-r" + ], + "started_at_utc": "2026-09-10T09:16:29.084857+00:00", + "returncode": 0, + "stdout": "[ 29] -> 0x26\n", + "stderr": "", + "finished_at_utc": "2026-09-10T09:16:29.100716+00:00" + }, + { + "command": [ + "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_transfer.exe", + "-d", + "000000000000000097c063dc2e5327d3", + "-r", + "C:\\Users\\user\\Desktop\\projects\\SDR_Rover\\data\\raw\\lab056\\preflight_rx.cs8", + "-f", + "1400000000", + "-s", + "8000000", + "-n", + "800000", + "-l", + "24", + "-g", + "24", + "-a", + "0", + "-p", + "0", + "-B" + ], + "started_at_utc": "2026-09-10T09:16:29.100863+00:00", + "returncode": 0, + "stdout": "", + "stderr": "call hackrf_set_sample_rate(8000000 Hz/8.000 MHz)\ncall hackrf_set_hw_sync_mode(0)\ncall hackrf_set_freq(1400000000 Hz/1400.000 MHz)\ncall hackrf_set_amp_enable(0)\ncall hackrf_set_antenna_enable(0)\nsamples_to_xfer 800000/0Mio\nStop with Ctrl-C\n 1.8 MiB / 0.119 sec = 15.4 MiB/second, average power -35.2 dBfs, 15552 bytes free in buffer, 0 overruns, longest 0 bytes\n\nExiting...\nTotal time: 0.11922 s\nhackrf_stop_rx() done\nTransfer statistics:\n1913376 bytes transferred by M0\n1900544 bytes transferred by M4\n0 overruns, longest 0 bytes\nhackrf_close() done\nhackrf_exit() done\nfclose() done\nexit\n", + "finished_at_utc": "2026-09-10T09:16:29.239488+00:00" + }, + { + "command": [ + "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_clock.exe", + "-d", + "000000000000000097c063dc323b97d3", + "-o", + "0" + ], + "started_at_utc": "2026-09-10T09:16:29.271470+00:00", + "returncode": 0, + "stdout": "", + "stderr": "", + "finished_at_utc": "2026-09-10T09:16:29.288606+00:00" + }, + { + "command": [ + "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_clock.exe", + "-d", + "000000000000000097c063dc2e5327d3", + "-o", + "0" + ], + "started_at_utc": "2026-09-10T09:16:29.288689+00:00", + "returncode": 0, + "stdout": "", + "stderr": "", + "finished_at_utc": "2026-09-10T09:16:29.309700+00:00" + } + ] +} diff --git a/data/processed/lab056/rx_preflight_plan.json b/data/processed/lab056/rx_preflight_plan.json new file mode 100644 index 0000000..8254419 --- /dev/null +++ b/data/processed/lab056/rx_preflight_plan.json @@ -0,0 +1,26 @@ +{ + "point": { + "frequency_hz": 1400000000, + "physical_path": "MASTER TX -> TX antenna -> free-space LOS -> RX antenna -> SLAVE RX; user-specified approximate distance 3-5 m; fixed equipment and cables", + "path_confirmed": true, + "tx_antenna": "Existing 1400 MHz antenna, as described by user; model/marking not supplied", + "rx_antenna": "Existing 1400 MHz antenna, as described by user; model/marking not supplied", + "distance_m": null, + "orientation": "Both stationary; same antenna orientation and polarization, per user", + "visibility": "LOS" + }, + "distance_description": "Approximately 3-5 m per user; exact measured value not supplied", + "frequency_role": "CURRENT_LAB056_TEST_ONLY_NOT_ROVER_OPERATING_BAND", + "field_band_context": "Approximately 180 MHz considered separately; 50/144 MHz outside Lab056", + "scope": "COMMON_CLOCK_AND_RX_ONLY_PREFLIGHT_THEN_STOP", + "tx_authorized": false, + "rf_tx_count": 0, + "rx_preflight_samples": 800000, + "sample_rate_hz": 8000000, + "rx_lna_db": 24, + "rx_vga_db": 24, + "rf_amplifier": false, + "bias_tee": false, + "external_pa_lna": false, + "recorded_at_utc": "2026-09-10T09:16:28.289788+00:00" +} diff --git a/data/processed/lab056/rx_preflight_result.json b/data/processed/lab056/rx_preflight_result.json new file mode 100644 index 0000000..bc95ef8 --- /dev/null +++ b/data/processed/lab056/rx_preflight_result.json @@ -0,0 +1,114 @@ +{ + "passed": true, + "rf_tx_count": 0, + "point": { + "frequency_hz": 1400000000, + "physical_path": "MASTER TX -> TX antenna -> free-space LOS -> RX antenna -> SLAVE RX; user-specified approximate distance 3-5 m; fixed equipment and cables", + "path_confirmed": true, + "tx_antenna": "Existing 1400 MHz antenna, as described by user; model/marking not supplied", + "rx_antenna": "Existing 1400 MHz antenna, as described by user; model/marking not supplied", + "distance_m": null, + "orientation": "Both stationary; same antenna orientation and polarization, per user", + "visibility": "LOS" + }, + "tx_sha256": "5b34bbe1a8e6d037d2d6d367a74e9eb84e8940db7da61600ffaa7f7497d4f600", + "stop_before_tx": true, + "process_before": { + "state": "CLEAR", + "attempts": [ + { + "state": "CLEAR", + "mechanism": "psutil", + "matches": [], + "inspected": 297, + "errors": [] + } + ] + }, + "inventory": { + "passed": true, + "serials": [ + "000000000000000097c063dc2e5327d3", + "000000000000000097c063dc323b97d3" + ], + "master_serial": "000000000000000097c063dc323b97d3", + "slave_serial": "000000000000000097c063dc2e5327d3", + "raw_output": "hackrf_info version: 2024.02.1\nlibhackrf version: 2024.02.1 (0.9)\nFound HackRF\nIndex: 0\nSerial number: 000000000000000097c063dc323b97d3\nBoard ID Number: 4 (HackRF One)\nFirmware Version: 2024.02.1 (API:1.08)\nPart ID Number: 0xa000cb3c 0x00744f5a\nHardware Revision: r9\nHardware does not appear to have been manufactured by Great Scott Gadgets.\nHardware supported by installed firmware:\n HackRF One\n\nFound HackRF\nIndex: 1\nSerial number: 000000000000000097c063dc2e5327d3\nBoard ID Number: 4 (HackRF One)\nFirmware Version: 2024.02.1 (API:1.08)\nPart ID Number: 0xa000cb3c 0xbc4b4739\nHardware Revision: r9\nHardware does not appear to have been manufactured by Great Scott Gadgets.\nHardware supported by installed firmware:\n HackRF One" + }, + "clock": { + "passed": true, + "master_reg29": 38, + "slave_reg29": 38, + "slave_clkin_status": "DETECTED", + "slave_clock_wait": { + "state": "DETECTED", + "queries": 1, + "time_to_detect_ms": 67.78709997888654, + "elapsed_ms": 67.78709997888654, + "polls": [ + { + "query": 1, + "start_ms": 50.16230000182986, + "end_ms": 67.78709997888654, + "raw": "CLKIN status: clock signal detected", + "state": "DETECTED", + "exit_code": 0 + } + ] + }, + "master_serial": "000000000000000097c063dc323b97d3", + "slave_serial": "000000000000000097c063dc2e5327d3" + }, + "rx_process": { + "returncode": 0, + "stdout": "", + "stderr": "call hackrf_set_sample_rate(8000000 Hz/8.000 MHz)\ncall hackrf_set_hw_sync_mode(0)\ncall hackrf_set_freq(1400000000 Hz/1400.000 MHz)\ncall hackrf_set_amp_enable(0)\ncall hackrf_set_antenna_enable(0)\nsamples_to_xfer 800000/0Mio\nStop with Ctrl-C\n 1.8 MiB / 0.119 sec = 15.4 MiB/second, average power -35.2 dBfs, 15552 bytes free in buffer, 0 overruns, longest 0 bytes\n\nExiting...\nTotal time: 0.11922 s\nhackrf_stop_rx() done\nTransfer statistics:\n1913376 bytes transferred by M0\n1900544 bytes transferred by M4\n0 overruns, longest 0 bytes\nhackrf_close() done\nhackrf_exit() done\nfclose() done\nexit\n" + }, + "rx_level": { + "samples": 800000, + "mean_i": 0.92535625, + "mean_q": 1.82532, + "power_code2": 4.85388125, + "ac_power_code2": 0.6658039581859372, + "rms_code": 2.20315257074947, + "peak_magnitude_code": 6.082762530298219, + "max_abs_i": 4.0, + "max_abs_q": 6.0, + "papr_db": 8.821125769372884, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.0002426940625, + "saturation_detected": false, + "analog_compression": "UNKNOWN_WITHOUT_CALIBRATION" + }, + "rx_sha256": "c4257f26e4cc8562eb32228f9a50fdeb055879c928af0744cdf4a81cf7cd085b", + "process_after": { + "state": "CLEAR", + "attempts": [ + { + "state": "CLEAR", + "mechanism": "psutil", + "matches": [], + "inspected": 297, + "errors": [] + } + ] + }, + "cleanup_errors": [], + "source_path": "data/raw/lab056/preflight_result.json", + "source_sha256": "b691e51653f9e814627fd100cf99de0f22fef837b177030227ecddc5af573cf3", + "ready_for_single_abab_tx": true, + "tx_authorization_received": false, + "verifier": { + "mode": "SAVED_FILES_READ_ONLY", + "passed": true, + "reproduced_discrepancies": 0, + "independent_recalculation": "INTEGER_MOMENTS_AND_RAIL_COUNTS", + "hardware_commands": 0 + }, + "audited_hardware_commands": 12, + "audited_rx_transfers": 3, + "audited_tx_commands": 0, + "frequency_role": "LAB056_TEST_ONLY_NOT_ROVER_OPERATING_BAND", + "stop": true +} diff --git a/data/processed/lab056/software_equal.json b/data/processed/lab056/software_equal.json new file mode 100644 index 0000000..8efa3a2 --- /dev/null +++ b/data/processed/lab056/software_equal.json @@ -0,0 +1,489 @@ +{ + "scope": "TX_REFERENCE_DIAGNOSTICS_NOT_INDEPENDENT_PACKET_RX", + "rf_tx": 0, + "tx_sha256": "5b34bbe1a8e6d037d2d6d367a74e9eb84e8940db7da61600ffaa7f7497d4f600", + "rx_sha256": "a88afcc1bbeb50092f9f5baca6eb607d25daf508e0fafcdcada318818d9ffd62", + "alignment": { + "start": 4109216, + "correlation": 0.712109578315035, + "coarse_cfo_hz": 0.25, + "stride": 32 + }, + "segments": [ + { + "label": "A1", + "symbol_rate": 20000, + "raw_rx": { + "samples": 1638400, + "mean_i": 0.9995880126953125, + "mean_q": 2.00025390625, + "power_code2": 7.596464233398438, + "ac_power_code2": 2.596272348805888, + "rms_code": 2.7561683971409363, + "peak_magnitude_code": 6.708203932499369, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 7.726010163935343, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.0003798232116699219, + "band_27000_power": 1.729349736724617, + "band_675000_power": 1.8014764601725908, + "power_standard_error": 0.039755811858960266 + }, + "local_zero_iq_background_windows": [ + { + "samples": 480000, + "mean_i": 1.0012270833333334, + "mean_q": 2.0008, + "power_code2": 5.88834375, + "ac_power_code2": 0.8826874375998264, + "rms_code": 2.4265909729494997, + "peak_magnitude_code": 5.385164807134504, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.924048425663756, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.0002944171875, + "band_27000_power": 0.002998337896541192, + "band_675000_power": 0.0744039583655369, + "power_standard_error": 0.0012691882704167598 + }, + { + "samples": 480000, + "mean_i": 0.9989395833333333, + "mean_q": 2.000110416666667, + "power_code2": 5.883275, + "ac_power_code2": 0.8849530299913191, + "rms_code": 2.42554633021099, + "peak_magnitude_code": 5.385164807134504, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.9277884895206405, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.00029416375, + "band_27000_power": 0.003012451963227414, + "band_675000_power": 0.07417080321149919, + "power_standard_error": 0.0013506571909630695 + } + ], + "background_power": 0.8838202337955727, + "background_subtracted_raw": 1.7124521150103154, + "background_subtracted_uncertainty": 0.039782742266144235, + "background_subtracted_stable": true, + "background_subtracted_signal_power": 1.7124521150103154, + "channel_gain_power": 0.0007924265932905088, + "measurement": { + "frame": 1, + "start": 4909213, + "alignment_adjustment": -3, + "rx_active": { + "samples": 1638400, + "mean_i": 0.9995880126953125, + "mean_q": 2.00025390625, + "power_code2": 7.596464233398438, + "ac_power_code2": 2.596272348805888, + "rms_code": 2.7561683971409363, + "peak_magnitude_code": 6.708203932499369, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 7.726010163935343, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.0003798232116699219 + }, + "cfo_hz": 0.1968177799965115, + "gain_abs": 0.028150072704888503, + "dc_i": 0.9997948620728929, + "dc_q": 2.0010324962850192, + "train_signal_power": 1.55023266362049, + "train_residual_power": 0.9894122701085495, + "train_actual_ac_power": 2.539644933729041, + "train_cross_power": 2.1058155219577658e-15, + "heldout_signal_power": 1.549823229026632, + "heldout_residual_power": 0.8945490859865625, + "heldout_actual_ac_power": 2.6529010618609536, + "heldout_cross_power": 0.20852874684775813, + "heldout_residual_band_27000_power": 0.010080618023636462, + "heldout_residual_band_675000_power": 0.08179753911385561, + "heldout_residual_band_1000000_power": 0.11760791625473926, + "heldout_residual_matched_power": 3.4888049404460095, + "effective_signal_to_residual_db": 2.3867798958438566 + } + }, + { + "label": "B1", + "symbol_rate": 500000, + "raw_rx": { + "samples": 1638400, + "mean_i": 0.998636474609375, + "mean_q": 1.9995599365234376, + "power_code2": 7.572622680664063, + "ac_power_code2": 2.5771079324942088, + "rms_code": 2.751839871915527, + "peak_magnitude_code": 7.211102550927978, + "max_abs_i": 5.0, + "max_abs_q": 7.0, + "papr_db": 8.367570257627738, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.5145245361328126e-05, + "band_27000_power": 0.08434245734375428, + "band_675000_power": 1.7818539229368797, + "power_standard_error": 0.03929664272862704 + }, + "local_zero_iq_background_windows": [ + { + "samples": 480000, + "mean_i": 0.9989395833333333, + "mean_q": 2.000110416666667, + "power_code2": 5.883275, + "ac_power_code2": 0.8849530299913191, + "rms_code": 2.42554633021099, + "peak_magnitude_code": 5.385164807134504, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.9277884895206405, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.176655e-05, + "band_27000_power": 0.003012451963227414, + "band_675000_power": 0.07417080321149919, + "power_standard_error": 0.0013506571909630695 + }, + { + "samples": 480000, + "mean_i": 0.9989791666666666, + "mean_q": 2.00009375, + "power_code2": 5.883064583333334, + "ac_power_code2": 0.8847301991102432, + "rms_code": 2.4255029547154408, + "peak_magnitude_code": 5.0990195135927845, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.45369731942485, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.1766129166666667e-05, + "band_27000_power": 0.0030190450807723868, + "band_675000_power": 0.07463668207172841, + "power_standard_error": 0.0009021263608471298 + } + ], + "background_power": 0.8848416145507811, + "background_subtracted_raw": 1.6922663179434276, + "background_subtracted_uncertainty": 0.03930519138544367, + "background_subtracted_stable": true, + "background_subtracted_signal_power": 1.6922663179434276, + "channel_gain_power": 0.0007927525626002337, + "measurement": { + "frame": 1, + "start": 7364413, + "alignment_adjustment": -3, + "rx_active": { + "samples": 1638400, + "mean_i": 0.998636474609375, + "mean_q": 1.9995599365234376, + "power_code2": 7.572622680664063, + "ac_power_code2": 2.5771079324942088, + "rms_code": 2.751839871915527, + "peak_magnitude_code": 7.211102550927978, + "max_abs_i": 5.0, + "max_abs_q": 7.0, + "papr_db": 8.367570257627738, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.5145245361328126e-05 + }, + "cfo_hz": 0.20030217648162243, + "gain_abs": 0.028155861958040526, + "dc_i": 0.9986008794024919, + "dc_q": 2.00024705167195, + "train_signal_power": 1.5355362521933293, + "train_residual_power": 0.9879108077929747, + "train_actual_ac_power": 2.523447059986303, + "train_cross_power": -1.306454944227653e-15, + "heldout_signal_power": 1.5355180397870447, + "heldout_residual_power": 0.8925132940453717, + "heldout_actual_ac_power": 2.630769751790605, + "heldout_cross_power": 0.2027384179581883, + "heldout_residual_band_27000_power": 0.0033142687288771526, + "heldout_residual_band_675000_power": 0.0813443897071584, + "heldout_residual_band_1000000_power": 0.11762789507725498, + "heldout_residual_matched_power": 0.9819762872749349, + "effective_signal_to_residual_db": 2.3564022937017817 + } + }, + { + "label": "A2", + "symbol_rate": 20000, + "raw_rx": { + "samples": 1638400, + "mean_i": 1.000250244140625, + "mean_q": 2.0000390625, + "power_code2": 7.5943505859375, + "ac_power_code2": 2.5936937835082423, + "rms_code": 2.755784931001964, + "peak_magnitude_code": 7.211102550927978, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 8.355127015785026, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.000379717529296875, + "band_27000_power": 1.7263462989934586, + "band_675000_power": 1.7983862355807485, + "power_standard_error": 0.03961683202831068 + }, + "local_zero_iq_background_windows": [ + { + "samples": 480000, + "mean_i": 0.9989791666666666, + "mean_q": 2.00009375, + "power_code2": 5.883064583333334, + "ac_power_code2": 0.8847301991102432, + "rms_code": 2.4255029547154408, + "peak_magnitude_code": 5.0990195135927845, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.45369731942485, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.00029415322916666667, + "band_27000_power": 0.0030190450807723868, + "band_675000_power": 0.07463668207172841, + "power_standard_error": 0.0009021263608471298 + }, + { + "samples": 480000, + "mean_i": 1.0004854166666666, + "mean_q": 2.0000104166666666, + "power_code2": 5.883220833333334, + "ac_power_code2": 0.8822080975954867, + "rms_code": 2.425535164315977, + "peak_magnitude_code": 5.830951894845301, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 7.6186376661535915, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.0002941610416666667, + "band_27000_power": 0.003053650977045963, + "band_675000_power": 0.073961606327725, + "power_standard_error": 0.0012067695631605175 + } + ], + "background_power": 0.8834691483528649, + "background_subtracted_raw": 1.7102246351553774, + "background_subtracted_uncertainty": 0.03964405579856132, + "background_subtracted_stable": true, + "background_subtracted_signal_power": 1.7102246351553774, + "channel_gain_power": 0.0007920055569282462, + "measurement": { + "frame": 1, + "start": 9803485, + "alignment_adjustment": -3, + "rx_active": { + "samples": 1638400, + "mean_i": 1.000250244140625, + "mean_q": 2.0000390625, + "power_code2": 7.5943505859375, + "ac_power_code2": 2.5936937835082423, + "rms_code": 2.755784931001964, + "peak_magnitude_code": 7.211102550927978, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 8.355127015785026, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.000379717529296875 + }, + "cfo_hz": 0.19617739757807567, + "gain_abs": 0.02814259328719097, + "dc_i": 1.0004532662364058, + "dc_q": 2.0003859700871685, + "train_signal_power": 1.5494089856585476, + "train_residual_power": 0.9895407718712785, + "train_actual_ac_power": 2.5389497575298265, + "train_cross_power": 4.0495384823202584e-16, + "heldout_signal_power": 1.548999768607681, + "heldout_residual_power": 0.8941535479569137, + "heldout_actual_ac_power": 2.6484381326123456, + "heldout_cross_power": 0.20528481604775145, + "heldout_residual_band_27000_power": 0.009765782070021769, + "heldout_residual_band_675000_power": 0.08171891866368976, + "heldout_residual_band_1000000_power": 0.1177276686242853, + "heldout_residual_matched_power": 3.3724974710374163, + "effective_signal_to_residual_db": 2.3863924873600086 + } + }, + { + "label": "B2", + "symbol_rate": 500000, + "raw_rx": { + "samples": 1638400, + "mean_i": 0.99942626953125, + "mean_q": 1.999466552734375, + "power_code2": 7.5732568359375, + "ac_power_code2": 2.5765374722048655, + "rms_code": 2.751955093372256, + "peak_magnitude_code": 6.708203932499369, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 7.739298282383329, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.5146513671875001e-05, + "band_27000_power": 0.08437478193987907, + "band_675000_power": 1.7815424066137258, + "power_standard_error": 0.03932113008198285 + }, + "local_zero_iq_background_windows": [ + { + "samples": 480000, + "mean_i": 1.0004854166666666, + "mean_q": 2.0000104166666666, + "power_code2": 5.883220833333334, + "ac_power_code2": 0.8822080975954867, + "rms_code": 2.425535164315977, + "peak_magnitude_code": 5.830951894845301, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 7.6186376661535915, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.1766441666666666e-05, + "band_27000_power": 0.003053650977045963, + "band_675000_power": 0.073961606327725, + "power_standard_error": 0.0012067695631605175 + }, + { + "samples": 480000, + "mean_i": 0.9988083333333333, + "mean_q": 1.9994125, + "power_code2": 5.878066666666666, + "ac_power_code2": 0.8827982347743042, + "rms_code": 2.4244724512080285, + "peak_magnitude_code": 5.0990195135927845, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.457388406130481, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.1756133333333333e-05, + "band_27000_power": 0.0029587129864172557, + "band_675000_power": 0.07444268200354834, + "power_standard_error": 0.0016031313210695718 + } + ], + "background_power": 0.8825031661848954, + "background_subtracted_raw": 1.69403430601997, + "background_subtracted_uncertainty": 0.039335034220138454, + "background_subtracted_stable": true, + "background_subtracted_signal_power": 1.69403430601997, + "channel_gain_power": 0.0007914780017038821, + "measurement": { + "frame": 1, + "start": 12258685, + "alignment_adjustment": -3, + "rx_active": { + "samples": 1638400, + "mean_i": 0.99942626953125, + "mean_q": 1.999466552734375, + "power_code2": 7.5732568359375, + "ac_power_code2": 2.5765374722048655, + "rms_code": 2.751955093372256, + "peak_magnitude_code": 6.708203932499369, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 7.739298282383329, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.5146513671875001e-05 + }, + "cfo_hz": 0.197924755610056, + "gain_abs": 0.028133218829417335, + "dc_i": 1.0007017709706703, + "dc_q": 1.999435627739676, + "train_signal_power": 1.5330674686733408, + "train_residual_power": 0.9881175175558363, + "train_actual_ac_power": 2.5211849862291755, + "train_cross_power": -1.4430123762565473e-15, + "heldout_signal_power": 1.5330492855483506, + "heldout_residual_power": 0.8931876810530448, + "heldout_actual_ac_power": 2.6318932139011078, + "heldout_cross_power": 0.20565624729971124, + "heldout_residual_band_27000_power": 0.0033209337668698995, + "heldout_residual_band_675000_power": 0.08160471700839024, + "heldout_residual_band_1000000_power": 0.11754379856225462, + "heldout_residual_matched_power": 0.9863150049618183, + "effective_signal_to_residual_db": 2.346133924823488 + } + } + ], + "pairs": [ + { + "pair": 1, + "received_power_difference_db": -0.051497256938167285, + "channel_gain_difference_db": 0.0017861283874782213, + "matched_component_difference_db": -0.04027242840779062, + "matched_component_symbol_energy_difference_db": -14.019672515128168 + }, + { + "pair": 2, + "received_power_difference_db": -0.04130956980203142, + "channel_gain_difference_db": -0.0028938012026523408, + "matched_component_difference_db": -0.044952357997923256, + "matched_component_symbol_energy_difference_db": -14.0243524447183 + } + ], + "outside_waveform_background": [ + { + "start": 3309216, + "samples": 400000, + "mean_i": 0.9997525, + "mean_q": 2.0, + "power_code2": 5.8853875, + "ac_power_code2": 0.8858824387437494, + "rms_code": 2.4259817600303593, + "peak_magnitude_code": 5.385164807134504, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.926229353802586, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.000294269375, + "band_27000_power": 0.00300239645688663, + "band_675000_power": 0.07464470494185707, + "power_standard_error": 0.001189001018090443 + }, + { + "start": 15097760, + "samples": 400000, + "mean_i": 1.00201, + "mean_q": 1.9998775, + "power_code2": 5.8860125, + "ac_power_code2": 0.8824784448937502, + "rms_code": 2.4261105704398553, + "peak_magnitude_code": 5.0990195135927845, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.451521679042596, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.000294300625, + "band_27000_power": 0.002877436011683443, + "band_675000_power": 0.07431026562360402, + "power_standard_error": 0.0010078630955450837 + } + ], + "background_note": "Внутренние gaps: нулевой цифровой IQ при работающем TX; это не RF OFF. Внешние окна также требуют сверки времён запуска/остановки по журналам.", + "power_units": "RX code squared, not calibrated watts/dBm", + "residual_note": "Шум и неописанные моделью искажения; RX не нормируется для выравнивания A/B", + "synthetic": true, + "expected_gain_difference_db": 0.0, + "known_sequence_start": 4160013, + "passed": true +} diff --git a/data/processed/lab056/software_equal_ota_summary.json b/data/processed/lab056/software_equal_ota_summary.json new file mode 100644 index 0000000..9d73089 --- /dev/null +++ b/data/processed/lab056/software_equal_ota_summary.json @@ -0,0 +1,532 @@ +{ + "scope": "TX_REFERENCE_DIAGNOSTICS_NOT_INDEPENDENT_PACKET_RX", + "rf_tx": 0, + "tx_sha256": "5b34bbe1a8e6d037d2d6d367a74e9eb84e8940db7da61600ffaa7f7497d4f600", + "rx_sha256": "a88afcc1bbeb50092f9f5baca6eb607d25daf508e0fafcdcada318818d9ffd62", + "alignment": { + "start": 4109216, + "correlation": 0.712109578315035, + "coarse_cfo_hz": 0.25, + "stride": 32 + }, + "segments": [ + { + "label": "A1", + "symbol_rate": 20000, + "raw_rx": { + "samples": 1638400, + "mean_i": 0.9995880126953125, + "mean_q": 2.00025390625, + "power_code2": 7.596464233398438, + "ac_power_code2": 2.596272348805888, + "rms_code": 2.7561683971409363, + "peak_magnitude_code": 6.708203932499369, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 7.726010163935343, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.0003798232116699219, + "band_27000_power": 1.729349736724617, + "band_675000_power": 1.8014764601725908, + "power_standard_error": 0.039755811858960266 + }, + "local_zero_iq_background_windows": [ + { + "samples": 480000, + "mean_i": 1.0012270833333334, + "mean_q": 2.0008, + "power_code2": 5.88834375, + "ac_power_code2": 0.8826874375998264, + "rms_code": 2.4265909729494997, + "peak_magnitude_code": 5.385164807134504, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.924048425663756, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.0002944171875, + "band_27000_power": 0.002998337896541192, + "band_675000_power": 0.0744039583655369, + "power_standard_error": 0.0012691882704167598 + }, + { + "samples": 480000, + "mean_i": 0.9989395833333333, + "mean_q": 2.000110416666667, + "power_code2": 5.883275, + "ac_power_code2": 0.8849530299913191, + "rms_code": 2.42554633021099, + "peak_magnitude_code": 5.385164807134504, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.9277884895206405, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.00029416375, + "band_27000_power": 0.003012451963227414, + "band_675000_power": 0.07417080321149919, + "power_standard_error": 0.0013506571909630695 + } + ], + "background_power": 0.8838202337955727, + "background_subtracted_raw": 1.7124521150103154, + "background_subtracted_uncertainty": 0.039782742266144235, + "background_subtracted_stable": true, + "background_subtracted_signal_power": 1.7124521150103154, + "channel_gain_complex": { + "real": -0.0027287468398317707, + "imag": -0.028017504063970737, + "phase_rad_at_active_start": -1.6678844763817968 + }, + "channel_gain_power": 0.0007924265932905088, + "measurement": { + "frame": 1, + "start": 4909213, + "alignment_adjustment": -3, + "rx_active": { + "samples": 1638400, + "mean_i": 0.9995880126953125, + "mean_q": 2.00025390625, + "power_code2": 7.596464233398438, + "ac_power_code2": 2.596272348805888, + "rms_code": 2.7561683971409363, + "peak_magnitude_code": 6.708203932499369, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 7.726010163935343, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.0003798232116699219 + }, + "cfo_hz": 0.1968177799965115, + "gain_abs": 0.028150072704888503, + "dc_i": 0.9997948620728929, + "dc_q": 2.0010324962850192, + "train_signal_power": 1.55023266362049, + "train_residual_power": 0.9894122701085495, + "train_actual_ac_power": 2.539644933729041, + "train_cross_power": 2.1058155219577658e-15, + "heldout_signal_power": 1.549823229026632, + "heldout_residual_power": 0.8945490859865625, + "heldout_actual_ac_power": 2.6529010618609536, + "heldout_cross_power": 0.20852874684775813, + "heldout_residual_band_27000_power": 0.010080618023636462, + "heldout_residual_band_675000_power": 0.08179753911385561, + "heldout_residual_band_1000000_power": 0.11760791625473926, + "heldout_residual_matched_power": 3.4888049404460095, + "effective_signal_to_residual_db": 2.3867798958438566 + } + }, + { + "label": "B1", + "symbol_rate": 500000, + "raw_rx": { + "samples": 1638400, + "mean_i": 0.998636474609375, + "mean_q": 1.9995599365234376, + "power_code2": 7.572622680664063, + "ac_power_code2": 2.5771079324942088, + "rms_code": 2.751839871915527, + "peak_magnitude_code": 7.211102550927978, + "max_abs_i": 5.0, + "max_abs_q": 7.0, + "papr_db": 8.367570257627738, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.5145245361328126e-05, + "band_27000_power": 0.08434245734375428, + "band_675000_power": 1.7818539229368797, + "power_standard_error": 0.03929664272862704 + }, + "local_zero_iq_background_windows": [ + { + "samples": 480000, + "mean_i": 0.9989395833333333, + "mean_q": 2.000110416666667, + "power_code2": 5.883275, + "ac_power_code2": 0.8849530299913191, + "rms_code": 2.42554633021099, + "peak_magnitude_code": 5.385164807134504, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.9277884895206405, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.176655e-05, + "band_27000_power": 0.003012451963227414, + "band_675000_power": 0.07417080321149919, + "power_standard_error": 0.0013506571909630695 + }, + { + "samples": 480000, + "mean_i": 0.9989791666666666, + "mean_q": 2.00009375, + "power_code2": 5.883064583333334, + "ac_power_code2": 0.8847301991102432, + "rms_code": 2.4255029547154408, + "peak_magnitude_code": 5.0990195135927845, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.45369731942485, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.1766129166666667e-05, + "band_27000_power": 0.0030190450807723868, + "band_675000_power": 0.07463668207172841, + "power_standard_error": 0.0009021263608471298 + } + ], + "background_power": 0.8848416145507811, + "background_subtracted_raw": 1.6922663179434276, + "background_subtracted_uncertainty": 0.03930519138544367, + "background_subtracted_stable": true, + "background_subtracted_signal_power": 1.6922663179434276, + "channel_gain_complex": { + "real": 0.007947194796737946, + "imag": -0.027011009930451232, + "phase_rad_at_active_start": -1.2846501572766547 + }, + "channel_gain_power": 0.0007927525626002337, + "measurement": { + "frame": 1, + "start": 7364413, + "alignment_adjustment": -3, + "rx_active": { + "samples": 1638400, + "mean_i": 0.998636474609375, + "mean_q": 1.9995599365234376, + "power_code2": 7.572622680664063, + "ac_power_code2": 2.5771079324942088, + "rms_code": 2.751839871915527, + "peak_magnitude_code": 7.211102550927978, + "max_abs_i": 5.0, + "max_abs_q": 7.0, + "papr_db": 8.367570257627738, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.5145245361328126e-05 + }, + "cfo_hz": 0.20030217648162243, + "gain_abs": 0.028155861958040526, + "dc_i": 0.9986008794024919, + "dc_q": 2.00024705167195, + "train_signal_power": 1.5355362521933293, + "train_residual_power": 0.9879108077929747, + "train_actual_ac_power": 2.523447059986303, + "train_cross_power": -1.306454944227653e-15, + "heldout_signal_power": 1.5355180397870447, + "heldout_residual_power": 0.8925132940453717, + "heldout_actual_ac_power": 2.630769751790605, + "heldout_cross_power": 0.2027384179581883, + "heldout_residual_band_27000_power": 0.0033142687288771526, + "heldout_residual_band_675000_power": 0.0813443897071584, + "heldout_residual_band_1000000_power": 0.11762789507725498, + "heldout_residual_matched_power": 0.9819762872749349, + "effective_signal_to_residual_db": 2.3564022937017817 + } + }, + { + "label": "A2", + "symbol_rate": 20000, + "raw_rx": { + "samples": 1638400, + "mean_i": 1.000250244140625, + "mean_q": 2.0000390625, + "power_code2": 7.5943505859375, + "ac_power_code2": 2.5936937835082423, + "rms_code": 2.755784931001964, + "peak_magnitude_code": 7.211102550927978, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 8.355127015785026, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.000379717529296875, + "band_27000_power": 1.7263462989934586, + "band_675000_power": 1.7983862355807485, + "power_standard_error": 0.03961683202831068 + }, + "local_zero_iq_background_windows": [ + { + "samples": 480000, + "mean_i": 0.9989791666666666, + "mean_q": 2.00009375, + "power_code2": 5.883064583333334, + "ac_power_code2": 0.8847301991102432, + "rms_code": 2.4255029547154408, + "peak_magnitude_code": 5.0990195135927845, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.45369731942485, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.00029415322916666667, + "band_27000_power": 0.0030190450807723868, + "band_675000_power": 0.07463668207172841, + "power_standard_error": 0.0009021263608471298 + }, + { + "samples": 480000, + "mean_i": 1.0004854166666666, + "mean_q": 2.0000104166666666, + "power_code2": 5.883220833333334, + "ac_power_code2": 0.8822080975954867, + "rms_code": 2.425535164315977, + "peak_magnitude_code": 5.830951894845301, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 7.6186376661535915, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.0002941610416666667, + "band_27000_power": 0.003053650977045963, + "band_675000_power": 0.073961606327725, + "power_standard_error": 0.0012067695631605175 + } + ], + "background_power": 0.8834691483528649, + "background_subtracted_raw": 1.7102246351553774, + "background_subtracted_uncertainty": 0.03964405579856132, + "background_subtracted_stable": true, + "background_subtracted_signal_power": 1.7102246351553774, + "channel_gain_complex": { + "real": 0.01755314566236957, + "imag": -0.02199755973474973, + "phase_rad_at_active_start": -0.8973012782222721 + }, + "channel_gain_power": 0.0007920055569282462, + "measurement": { + "frame": 1, + "start": 9803485, + "alignment_adjustment": -3, + "rx_active": { + "samples": 1638400, + "mean_i": 1.000250244140625, + "mean_q": 2.0000390625, + "power_code2": 7.5943505859375, + "ac_power_code2": 2.5936937835082423, + "rms_code": 2.755784931001964, + "peak_magnitude_code": 7.211102550927978, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 8.355127015785026, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.000379717529296875 + }, + "cfo_hz": 0.19617739757807567, + "gain_abs": 0.02814259328719097, + "dc_i": 1.0004532662364058, + "dc_q": 2.0003859700871685, + "train_signal_power": 1.5494089856585476, + "train_residual_power": 0.9895407718712785, + "train_actual_ac_power": 2.5389497575298265, + "train_cross_power": 4.0495384823202584e-16, + "heldout_signal_power": 1.548999768607681, + "heldout_residual_power": 0.8941535479569137, + "heldout_actual_ac_power": 2.6484381326123456, + "heldout_cross_power": 0.20528481604775145, + "heldout_residual_band_27000_power": 0.009765782070021769, + "heldout_residual_band_675000_power": 0.08171891866368976, + "heldout_residual_band_1000000_power": 0.1177276686242853, + "heldout_residual_matched_power": 3.3724974710374163, + "effective_signal_to_residual_db": 2.3863924873600086 + } + }, + { + "label": "B2", + "symbol_rate": 500000, + "raw_rx": { + "samples": 1638400, + "mean_i": 0.99942626953125, + "mean_q": 1.999466552734375, + "power_code2": 7.5732568359375, + "ac_power_code2": 2.5765374722048655, + "rms_code": 2.751955093372256, + "peak_magnitude_code": 6.708203932499369, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 7.739298282383329, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.5146513671875001e-05, + "band_27000_power": 0.08437478193987907, + "band_675000_power": 1.7815424066137258, + "power_standard_error": 0.03932113008198285 + }, + "local_zero_iq_background_windows": [ + { + "samples": 480000, + "mean_i": 1.0004854166666666, + "mean_q": 2.0000104166666666, + "power_code2": 5.883220833333334, + "ac_power_code2": 0.8822080975954867, + "rms_code": 2.425535164315977, + "peak_magnitude_code": 5.830951894845301, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 7.6186376661535915, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.1766441666666666e-05, + "band_27000_power": 0.003053650977045963, + "band_675000_power": 0.073961606327725, + "power_standard_error": 0.0012067695631605175 + }, + { + "samples": 480000, + "mean_i": 0.9988083333333333, + "mean_q": 1.9994125, + "power_code2": 5.878066666666666, + "ac_power_code2": 0.8827982347743042, + "rms_code": 2.4244724512080285, + "peak_magnitude_code": 5.0990195135927845, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.457388406130481, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.1756133333333333e-05, + "band_27000_power": 0.0029587129864172557, + "band_675000_power": 0.07444268200354834, + "power_standard_error": 0.0016031313210695718 + } + ], + "background_power": 0.8825031661848954, + "background_subtracted_raw": 1.69403430601997, + "background_subtracted_uncertainty": 0.039335034220138454, + "background_subtracted_stable": true, + "background_subtracted_signal_power": 1.69403430601997, + "channel_gain_complex": { + "real": 0.02447249803166995, + "imag": -0.013877133774443209, + "phase_rad_at_active_start": -0.5158392359795115 + }, + "channel_gain_power": 0.0007914780017038821, + "measurement": { + "frame": 1, + "start": 12258685, + "alignment_adjustment": -3, + "rx_active": { + "samples": 1638400, + "mean_i": 0.99942626953125, + "mean_q": 1.999466552734375, + "power_code2": 7.5732568359375, + "ac_power_code2": 2.5765374722048655, + "rms_code": 2.751955093372256, + "peak_magnitude_code": 6.708203932499369, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 7.739298282383329, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.5146513671875001e-05 + }, + "cfo_hz": 0.197924755610056, + "gain_abs": 0.028133218829417335, + "dc_i": 1.0007017709706703, + "dc_q": 1.999435627739676, + "train_signal_power": 1.5330674686733408, + "train_residual_power": 0.9881175175558363, + "train_actual_ac_power": 2.5211849862291755, + "train_cross_power": -1.4430123762565473e-15, + "heldout_signal_power": 1.5330492855483506, + "heldout_residual_power": 0.8931876810530448, + "heldout_actual_ac_power": 2.6318932139011078, + "heldout_cross_power": 0.20565624729971124, + "heldout_residual_band_27000_power": 0.0033209337668698995, + "heldout_residual_band_675000_power": 0.08160471700839024, + "heldout_residual_band_1000000_power": 0.11754379856225462, + "heldout_residual_matched_power": 0.9863150049618183, + "effective_signal_to_residual_db": 2.346133924823488 + } + } + ], + "pairs": [ + { + "pair": 1, + "received_power_difference_db": -0.051497256938167285, + "channel_gain_difference_db": 0.0017861283874782213, + "matched_component_difference_db": -0.04027242840779062, + "matched_component_symbol_energy_difference_db": -14.019672515128168 + }, + { + "pair": 2, + "received_power_difference_db": -0.04130956980203142, + "channel_gain_difference_db": -0.0028938012026523408, + "matched_component_difference_db": -0.044952357997923256, + "matched_component_symbol_energy_difference_db": -14.0243524447183 + } + ], + "comparison_summary": { + "repeatability": [ + { + "comparison": "A2/A1", + "raw_rx_power_difference_db": -0.0012085532551280598, + "background_difference_db": -0.0017255178918689754, + "received_power_difference_db": -0.005652782408264756, + "channel_gain_difference_db": -0.0023081300526506692, + "matched_component_difference_db": -0.00230813005264874 + }, + { + "comparison": "B2/B1", + "raw_rx_power_difference_db": 0.00036367664985406537, + "background_difference_db": -0.011492673362299905, + "received_power_difference_db": 0.004534904727870617, + "channel_gain_difference_db": -0.006988059642781434, + "matched_component_difference_db": -0.006988059642780951 + } + ], + "averaging": "RATIO_OF_MEAN_LINEAR_POWERS_B1_B2_OVER_A1_A2", + "received_power_difference_db": -0.04640374115997541, + "channel_gain_difference_db": -0.000552584218408658, + "energy_per_symbol_difference_db": -14.025803827880353, + "energy_basis": "BACKGROUND_SUBTRACTED_RECEIVED_POWER_DIVIDED_BY_SYMBOL_RATE" + }, + "outside_waveform_background": [ + { + "start": 3309216, + "samples": 400000, + "mean_i": 0.9997525, + "mean_q": 2.0, + "power_code2": 5.8853875, + "ac_power_code2": 0.8858824387437494, + "rms_code": 2.4259817600303593, + "peak_magnitude_code": 5.385164807134504, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.926229353802586, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.000294269375, + "band_27000_power": 0.00300239645688663, + "band_675000_power": 0.07464470494185707, + "power_standard_error": 0.001189001018090443 + }, + { + "start": 15097760, + "samples": 400000, + "mean_i": 1.00201, + "mean_q": 1.9998775, + "power_code2": 5.8860125, + "ac_power_code2": 0.8824784448937502, + "rms_code": 2.4261105704398553, + "peak_magnitude_code": 5.0990195135927845, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.451521679042596, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.000294300625, + "band_27000_power": 0.002877436011683443, + "band_675000_power": 0.07431026562360402, + "power_standard_error": 0.0010078630955450837 + } + ], + "background_note": "Внутренние gaps: нулевой цифровой IQ при работающем TX; это не RF OFF. Внешние окна также требуют сверки времён запуска/остановки по журналам.", + "power_units": "RX code squared, not calibrated watts/dBm", + "residual_note": "Шум и неописанные моделью искажения; RX не нормируется для выравнивания A/B", + "synthetic": true, + "source_result_preserved": "software_equal.json" +} diff --git a/data/processed/lab056/software_minus6db.json b/data/processed/lab056/software_minus6db.json new file mode 100644 index 0000000..7d59bd0 --- /dev/null +++ b/data/processed/lab056/software_minus6db.json @@ -0,0 +1,489 @@ +{ + "scope": "TX_REFERENCE_DIAGNOSTICS_NOT_INDEPENDENT_PACKET_RX", + "rf_tx": 0, + "tx_sha256": "5b34bbe1a8e6d037d2d6d367a74e9eb84e8940db7da61600ffaa7f7497d4f600", + "rx_sha256": "a189c1ffaf029983d41f7d87e262cbbc28ba740fc8915a75e41ee0adec9c1fe6", + "alignment": { + "start": 4109216, + "correlation": 0.593709534474723, + "coarse_cfo_hz": 0.25, + "stride": 32 + }, + "segments": [ + { + "label": "A1", + "symbol_rate": 20000, + "raw_rx": { + "samples": 1638400, + "mean_i": 0.9995880126953125, + "mean_q": 2.00025390625, + "power_code2": 7.596464233398438, + "ac_power_code2": 2.596272348805888, + "rms_code": 2.7561683971409363, + "peak_magnitude_code": 6.708203932499369, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 7.726010163935343, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.0003798232116699219, + "band_27000_power": 1.729349736724617, + "band_675000_power": 1.8014764601725908, + "power_standard_error": 0.039755811858960266 + }, + "local_zero_iq_background_windows": [ + { + "samples": 480000, + "mean_i": 1.0012270833333334, + "mean_q": 2.0008, + "power_code2": 5.88834375, + "ac_power_code2": 0.8826874375998264, + "rms_code": 2.4265909729494997, + "peak_magnitude_code": 5.385164807134504, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.924048425663756, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.0002944171875, + "band_27000_power": 0.002998337896541192, + "band_675000_power": 0.0744039583655369, + "power_standard_error": 0.0012691882704167598 + }, + { + "samples": 480000, + "mean_i": 0.9989395833333333, + "mean_q": 2.000110416666667, + "power_code2": 5.883275, + "ac_power_code2": 0.8849530299913191, + "rms_code": 2.42554633021099, + "peak_magnitude_code": 5.385164807134504, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.9277884895206405, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.00029416375, + "band_27000_power": 0.003012451963227414, + "band_675000_power": 0.07417080321149919, + "power_standard_error": 0.0013506571909630695 + } + ], + "background_power": 0.8838202337955727, + "background_subtracted_raw": 1.7124521150103154, + "background_subtracted_uncertainty": 0.039782742266144235, + "background_subtracted_stable": true, + "background_subtracted_signal_power": 1.7124521150103154, + "channel_gain_power": 0.0007924265932905088, + "measurement": { + "frame": 1, + "start": 4909213, + "alignment_adjustment": -3, + "rx_active": { + "samples": 1638400, + "mean_i": 0.9995880126953125, + "mean_q": 2.00025390625, + "power_code2": 7.596464233398438, + "ac_power_code2": 2.596272348805888, + "rms_code": 2.7561683971409363, + "peak_magnitude_code": 6.708203932499369, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 7.726010163935343, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.0003798232116699219 + }, + "cfo_hz": 0.1968177799965115, + "gain_abs": 0.028150072704888503, + "dc_i": 0.9997948620728929, + "dc_q": 2.0010324962850192, + "train_signal_power": 1.55023266362049, + "train_residual_power": 0.9894122701085495, + "train_actual_ac_power": 2.539644933729041, + "train_cross_power": 2.1058155219577658e-15, + "heldout_signal_power": 1.549823229026632, + "heldout_residual_power": 0.8945490859865625, + "heldout_actual_ac_power": 2.6529010618609536, + "heldout_cross_power": 0.20852874684775813, + "heldout_residual_band_27000_power": 0.010080618023636462, + "heldout_residual_band_675000_power": 0.08179753911385561, + "heldout_residual_band_1000000_power": 0.11760791625473926, + "heldout_residual_matched_power": 3.4888049404460095, + "effective_signal_to_residual_db": 2.3867798958438566 + } + }, + { + "label": "B1", + "symbol_rate": 500000, + "raw_rx": { + "samples": 1638400, + "mean_i": 0.998985595703125, + "mean_q": 1.99885986328125, + "power_code2": 6.303458251953125, + "ac_power_code2": 1.3100452784940613, + "rms_code": 2.5106688853676276, + "peak_magnitude_code": 6.4031242374328485, + "max_abs_i": 4.0, + "max_abs_q": 6.0, + "papr_db": 8.132049758894885, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.260691650390625e-05, + "band_27000_power": 0.023313641821752495, + "band_675000_power": 0.5022288931564798, + "power_standard_error": 0.009890376052273048 + }, + "local_zero_iq_background_windows": [ + { + "samples": 480000, + "mean_i": 0.9989395833333333, + "mean_q": 2.000110416666667, + "power_code2": 5.883275, + "ac_power_code2": 0.8849530299913191, + "rms_code": 2.42554633021099, + "peak_magnitude_code": 5.385164807134504, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.9277884895206405, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.176655e-05, + "band_27000_power": 0.003012451963227414, + "band_675000_power": 0.07417080321149919, + "power_standard_error": 0.0013506571909630695 + }, + { + "samples": 480000, + "mean_i": 0.9989791666666666, + "mean_q": 2.00009375, + "power_code2": 5.883064583333334, + "ac_power_code2": 0.8847301991102432, + "rms_code": 2.4255029547154408, + "peak_magnitude_code": 5.0990195135927845, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.45369731942485, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.1766129166666667e-05, + "band_27000_power": 0.0030190450807723868, + "band_675000_power": 0.07463668207172841, + "power_standard_error": 0.0009021263608471298 + } + ], + "background_power": 0.8848416145507811, + "background_subtracted_raw": 0.42520366394328013, + "background_subtracted_uncertainty": 0.009924287307427941, + "background_subtracted_stable": true, + "background_subtracted_signal_power": 0.42520366394328013, + "channel_gain_power": 0.0001984013788928856, + "measurement": { + "frame": 1, + "start": 7364413, + "alignment_adjustment": -3, + "rx_active": { + "samples": 1638400, + "mean_i": 0.998985595703125, + "mean_q": 1.99885986328125, + "power_code2": 6.303458251953125, + "ac_power_code2": 1.3100452784940613, + "rms_code": 2.5106688853676276, + "peak_magnitude_code": 6.4031242374328485, + "max_abs_i": 4.0, + "max_abs_q": 6.0, + "papr_db": 8.132049758894885, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.260691650390625e-05 + }, + "cfo_hz": 0.2030817936052521, + "gain_abs": 0.014085502436650445, + "dc_i": 0.9994693255003283, + "dc_q": 1.9991360434375782, + "train_signal_power": 0.38429709867591966, + "train_residual_power": 0.9122921896535339, + "train_actual_ac_power": 1.2965892883294532, + "train_cross_power": 1.1296519275560969e-16, + "heldout_signal_power": 0.38429254067549146, + "heldout_residual_power": 0.8884947950547913, + "heldout_actual_ac_power": 1.3235018891986572, + "heldout_cross_power": 0.050714553468375057, + "heldout_residual_band_27000_power": 0.00304194937150677, + "heldout_residual_band_675000_power": 0.07681375917338087, + "heldout_residual_band_1000000_power": 0.11305538222420118, + "heldout_residual_matched_power": 0.9157792365512673, + "effective_signal_to_residual_db": -3.639929333248138 + } + }, + { + "label": "A2", + "symbol_rate": 20000, + "raw_rx": { + "samples": 1638400, + "mean_i": 1.000250244140625, + "mean_q": 2.0000390625, + "power_code2": 7.5943505859375, + "ac_power_code2": 2.5936937835082423, + "rms_code": 2.755784931001964, + "peak_magnitude_code": 7.211102550927978, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 8.355127015785026, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.000379717529296875, + "band_27000_power": 1.7263462989934586, + "band_675000_power": 1.7983862355807485, + "power_standard_error": 0.03961683202831068 + }, + "local_zero_iq_background_windows": [ + { + "samples": 480000, + "mean_i": 0.9989791666666666, + "mean_q": 2.00009375, + "power_code2": 5.883064583333334, + "ac_power_code2": 0.8847301991102432, + "rms_code": 2.4255029547154408, + "peak_magnitude_code": 5.0990195135927845, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.45369731942485, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.00029415322916666667, + "band_27000_power": 0.0030190450807723868, + "band_675000_power": 0.07463668207172841, + "power_standard_error": 0.0009021263608471298 + }, + { + "samples": 480000, + "mean_i": 1.0004854166666666, + "mean_q": 2.0000104166666666, + "power_code2": 5.883220833333334, + "ac_power_code2": 0.8822080975954867, + "rms_code": 2.425535164315977, + "peak_magnitude_code": 5.830951894845301, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 7.6186376661535915, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.0002941610416666667, + "band_27000_power": 0.003053650977045963, + "band_675000_power": 0.073961606327725, + "power_standard_error": 0.0012067695631605175 + } + ], + "background_power": 0.8834691483528649, + "background_subtracted_raw": 1.7102246351553774, + "background_subtracted_uncertainty": 0.03964405579856132, + "background_subtracted_stable": true, + "background_subtracted_signal_power": 1.7102246351553774, + "channel_gain_power": 0.0007920055569282462, + "measurement": { + "frame": 1, + "start": 9803485, + "alignment_adjustment": -3, + "rx_active": { + "samples": 1638400, + "mean_i": 1.000250244140625, + "mean_q": 2.0000390625, + "power_code2": 7.5943505859375, + "ac_power_code2": 2.5936937835082423, + "rms_code": 2.755784931001964, + "peak_magnitude_code": 7.211102550927978, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 8.355127015785026, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.000379717529296875 + }, + "cfo_hz": 0.19617739757807567, + "gain_abs": 0.02814259328719097, + "dc_i": 1.0004532662364058, + "dc_q": 2.0003859700871685, + "train_signal_power": 1.5494089856585476, + "train_residual_power": 0.9895407718712785, + "train_actual_ac_power": 2.5389497575298265, + "train_cross_power": 4.0495384823202584e-16, + "heldout_signal_power": 1.548999768607681, + "heldout_residual_power": 0.8941535479569137, + "heldout_actual_ac_power": 2.6484381326123456, + "heldout_cross_power": 0.20528481604775145, + "heldout_residual_band_27000_power": 0.009765782070021769, + "heldout_residual_band_675000_power": 0.08171891866368976, + "heldout_residual_band_1000000_power": 0.1177276686242853, + "heldout_residual_matched_power": 3.3724974710374163, + "effective_signal_to_residual_db": 2.3863924873600086 + } + }, + { + "label": "B2", + "symbol_rate": 500000, + "raw_rx": { + "samples": 1638400, + "mean_i": 0.9994140625, + "mean_q": 1.999407958984375, + "power_code2": 6.305787353515625, + "ac_power_code2": 1.3093266987428072, + "rms_code": 2.511132683375298, + "peak_magnitude_code": 5.830951894845301, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 7.317395958495091, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.261157470703125e-05, + "band_27000_power": 0.023440988618055048, + "band_675000_power": 0.5015327722551061, + "power_standard_error": 0.009843366386499481 + }, + "local_zero_iq_background_windows": [ + { + "samples": 480000, + "mean_i": 1.0004854166666666, + "mean_q": 2.0000104166666666, + "power_code2": 5.883220833333334, + "ac_power_code2": 0.8822080975954867, + "rms_code": 2.425535164315977, + "peak_magnitude_code": 5.830951894845301, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 7.6186376661535915, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.1766441666666666e-05, + "band_27000_power": 0.003053650977045963, + "band_675000_power": 0.073961606327725, + "power_standard_error": 0.0012067695631605175 + }, + { + "samples": 480000, + "mean_i": 0.9988083333333333, + "mean_q": 1.9994125, + "power_code2": 5.878066666666666, + "ac_power_code2": 0.8827982347743042, + "rms_code": 2.4244724512080285, + "peak_magnitude_code": 5.0990195135927845, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.457388406130481, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.1756133333333333e-05, + "band_27000_power": 0.0029587129864172557, + "band_675000_power": 0.07444268200354834, + "power_standard_error": 0.0016031313210695718 + } + ], + "background_power": 0.8825031661848954, + "background_subtracted_raw": 0.4268235325579117, + "background_subtracted_uncertainty": 0.009898762952718625, + "background_subtracted_stable": true, + "background_subtracted_signal_power": 0.4268235325579117, + "channel_gain_power": 0.00019792959281029668, + "measurement": { + "frame": 1, + "start": 12258685, + "alignment_adjustment": -3, + "rx_active": { + "samples": 1638400, + "mean_i": 0.9994140625, + "mean_q": 1.999407958984375, + "power_code2": 6.305787353515625, + "ac_power_code2": 1.3093266987428072, + "rms_code": 2.511132683375298, + "peak_magnitude_code": 5.830951894845301, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 7.317395958495091, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.261157470703125e-05 + }, + "cfo_hz": 0.20036016971332649, + "gain_abs": 0.014068745246477977, + "dc_i": 1.0007268354608458, + "dc_q": 1.9995225464921158, + "train_signal_power": 0.3833832641867325, + "train_residual_power": 0.9125567848168452, + "train_actual_ac_power": 1.2959400490035784, + "train_cross_power": 3.459732500488144e-16, + "heldout_signal_power": 0.3833787170249446, + "heldout_residual_power": 0.8881519217870418, + "heldout_actual_ac_power": 1.3227168214883227, + "heldout_cross_power": 0.051186182676336164, + "heldout_residual_band_27000_power": 0.003087916076869909, + "heldout_residual_band_675000_power": 0.0766452188649128, + "heldout_residual_band_1000000_power": 0.11237262287689712, + "heldout_residual_matched_power": 0.9135235192972193, + "effective_signal_to_residual_db": -3.648592601804231 + } + } + ], + "pairs": [ + { + "pair": 1, + "received_power_difference_db": -6.05021438090514, + "channel_gain_difference_db": -6.014143555521402, + "matched_component_difference_db": -6.056202112316672, + "matched_component_symbol_energy_difference_db": -20.035602199037047 + }, + { + "pair": 2, + "received_power_difference_db": -6.028048021201634, + "channel_gain_difference_db": -6.022174975174189, + "matched_component_difference_db": -6.06423353196946, + "matched_component_symbol_energy_difference_db": -20.04363361868984 + } + ], + "outside_waveform_background": [ + { + "start": 3309216, + "samples": 400000, + "mean_i": 0.9997525, + "mean_q": 2.0, + "power_code2": 5.8853875, + "ac_power_code2": 0.8858824387437494, + "rms_code": 2.4259817600303593, + "peak_magnitude_code": 5.385164807134504, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.926229353802586, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.000294269375, + "band_27000_power": 0.00300239645688663, + "band_675000_power": 0.07464470494185707, + "power_standard_error": 0.001189001018090443 + }, + { + "start": 15097760, + "samples": 400000, + "mean_i": 1.00201, + "mean_q": 1.9998775, + "power_code2": 5.8860125, + "ac_power_code2": 0.8824784448937502, + "rms_code": 2.4261105704398553, + "peak_magnitude_code": 5.0990195135927845, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.451521679042596, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.000294300625, + "band_27000_power": 0.002877436011683443, + "band_675000_power": 0.07431026562360402, + "power_standard_error": 0.0010078630955450837 + } + ], + "background_note": "Внутренние gaps: нулевой цифровой IQ при работающем TX; это не RF OFF. Внешние окна также требуют сверки времён запуска/остановки по журналам.", + "power_units": "RX code squared, not calibrated watts/dBm", + "residual_note": "Шум и неописанные моделью искажения; RX не нормируется для выравнивания A/B", + "synthetic": true, + "expected_gain_difference_db": -6.020599913279624, + "known_sequence_start": 4160013, + "passed": true +} diff --git a/data/processed/lab056/software_minus6db_ota_summary.json b/data/processed/lab056/software_minus6db_ota_summary.json new file mode 100644 index 0000000..bbe8feb --- /dev/null +++ b/data/processed/lab056/software_minus6db_ota_summary.json @@ -0,0 +1,532 @@ +{ + "scope": "TX_REFERENCE_DIAGNOSTICS_NOT_INDEPENDENT_PACKET_RX", + "rf_tx": 0, + "tx_sha256": "5b34bbe1a8e6d037d2d6d367a74e9eb84e8940db7da61600ffaa7f7497d4f600", + "rx_sha256": "a189c1ffaf029983d41f7d87e262cbbc28ba740fc8915a75e41ee0adec9c1fe6", + "alignment": { + "start": 4109216, + "correlation": 0.593709534474723, + "coarse_cfo_hz": 0.25, + "stride": 32 + }, + "segments": [ + { + "label": "A1", + "symbol_rate": 20000, + "raw_rx": { + "samples": 1638400, + "mean_i": 0.9995880126953125, + "mean_q": 2.00025390625, + "power_code2": 7.596464233398438, + "ac_power_code2": 2.596272348805888, + "rms_code": 2.7561683971409363, + "peak_magnitude_code": 6.708203932499369, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 7.726010163935343, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.0003798232116699219, + "band_27000_power": 1.729349736724617, + "band_675000_power": 1.8014764601725908, + "power_standard_error": 0.039755811858960266 + }, + "local_zero_iq_background_windows": [ + { + "samples": 480000, + "mean_i": 1.0012270833333334, + "mean_q": 2.0008, + "power_code2": 5.88834375, + "ac_power_code2": 0.8826874375998264, + "rms_code": 2.4265909729494997, + "peak_magnitude_code": 5.385164807134504, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.924048425663756, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.0002944171875, + "band_27000_power": 0.002998337896541192, + "band_675000_power": 0.0744039583655369, + "power_standard_error": 0.0012691882704167598 + }, + { + "samples": 480000, + "mean_i": 0.9989395833333333, + "mean_q": 2.000110416666667, + "power_code2": 5.883275, + "ac_power_code2": 0.8849530299913191, + "rms_code": 2.42554633021099, + "peak_magnitude_code": 5.385164807134504, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.9277884895206405, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.00029416375, + "band_27000_power": 0.003012451963227414, + "band_675000_power": 0.07417080321149919, + "power_standard_error": 0.0013506571909630695 + } + ], + "background_power": 0.8838202337955727, + "background_subtracted_raw": 1.7124521150103154, + "background_subtracted_uncertainty": 0.039782742266144235, + "background_subtracted_stable": true, + "background_subtracted_signal_power": 1.7124521150103154, + "channel_gain_complex": { + "real": -0.0027287468398317707, + "imag": -0.028017504063970737, + "phase_rad_at_active_start": -1.6678844763817968 + }, + "channel_gain_power": 0.0007924265932905088, + "measurement": { + "frame": 1, + "start": 4909213, + "alignment_adjustment": -3, + "rx_active": { + "samples": 1638400, + "mean_i": 0.9995880126953125, + "mean_q": 2.00025390625, + "power_code2": 7.596464233398438, + "ac_power_code2": 2.596272348805888, + "rms_code": 2.7561683971409363, + "peak_magnitude_code": 6.708203932499369, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 7.726010163935343, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.0003798232116699219 + }, + "cfo_hz": 0.1968177799965115, + "gain_abs": 0.028150072704888503, + "dc_i": 0.9997948620728929, + "dc_q": 2.0010324962850192, + "train_signal_power": 1.55023266362049, + "train_residual_power": 0.9894122701085495, + "train_actual_ac_power": 2.539644933729041, + "train_cross_power": 2.1058155219577658e-15, + "heldout_signal_power": 1.549823229026632, + "heldout_residual_power": 0.8945490859865625, + "heldout_actual_ac_power": 2.6529010618609536, + "heldout_cross_power": 0.20852874684775813, + "heldout_residual_band_27000_power": 0.010080618023636462, + "heldout_residual_band_675000_power": 0.08179753911385561, + "heldout_residual_band_1000000_power": 0.11760791625473926, + "heldout_residual_matched_power": 3.4888049404460095, + "effective_signal_to_residual_db": 2.3867798958438566 + } + }, + { + "label": "B1", + "symbol_rate": 500000, + "raw_rx": { + "samples": 1638400, + "mean_i": 0.998985595703125, + "mean_q": 1.99885986328125, + "power_code2": 6.303458251953125, + "ac_power_code2": 1.3100452784940613, + "rms_code": 2.5106688853676276, + "peak_magnitude_code": 6.4031242374328485, + "max_abs_i": 4.0, + "max_abs_q": 6.0, + "papr_db": 8.132049758894885, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.260691650390625e-05, + "band_27000_power": 0.023313641821752495, + "band_675000_power": 0.5022288931564798, + "power_standard_error": 0.009890376052273048 + }, + "local_zero_iq_background_windows": [ + { + "samples": 480000, + "mean_i": 0.9989395833333333, + "mean_q": 2.000110416666667, + "power_code2": 5.883275, + "ac_power_code2": 0.8849530299913191, + "rms_code": 2.42554633021099, + "peak_magnitude_code": 5.385164807134504, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.9277884895206405, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.176655e-05, + "band_27000_power": 0.003012451963227414, + "band_675000_power": 0.07417080321149919, + "power_standard_error": 0.0013506571909630695 + }, + { + "samples": 480000, + "mean_i": 0.9989791666666666, + "mean_q": 2.00009375, + "power_code2": 5.883064583333334, + "ac_power_code2": 0.8847301991102432, + "rms_code": 2.4255029547154408, + "peak_magnitude_code": 5.0990195135927845, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.45369731942485, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.1766129166666667e-05, + "band_27000_power": 0.0030190450807723868, + "band_675000_power": 0.07463668207172841, + "power_standard_error": 0.0009021263608471298 + } + ], + "background_power": 0.8848416145507811, + "background_subtracted_raw": 0.42520366394328013, + "background_subtracted_uncertainty": 0.009924287307427941, + "background_subtracted_stable": true, + "background_subtracted_signal_power": 0.42520366394328013, + "channel_gain_complex": { + "real": 0.003963777071987038, + "imag": -0.013516280931398084, + "phase_rad_at_active_start": -1.2855349404464855 + }, + "channel_gain_power": 0.0001984013788928856, + "measurement": { + "frame": 1, + "start": 7364413, + "alignment_adjustment": -3, + "rx_active": { + "samples": 1638400, + "mean_i": 0.998985595703125, + "mean_q": 1.99885986328125, + "power_code2": 6.303458251953125, + "ac_power_code2": 1.3100452784940613, + "rms_code": 2.5106688853676276, + "peak_magnitude_code": 6.4031242374328485, + "max_abs_i": 4.0, + "max_abs_q": 6.0, + "papr_db": 8.132049758894885, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.260691650390625e-05 + }, + "cfo_hz": 0.2030817936052521, + "gain_abs": 0.014085502436650445, + "dc_i": 0.9994693255003283, + "dc_q": 1.9991360434375782, + "train_signal_power": 0.38429709867591966, + "train_residual_power": 0.9122921896535339, + "train_actual_ac_power": 1.2965892883294532, + "train_cross_power": 1.1296519275560969e-16, + "heldout_signal_power": 0.38429254067549146, + "heldout_residual_power": 0.8884947950547913, + "heldout_actual_ac_power": 1.3235018891986572, + "heldout_cross_power": 0.050714553468375057, + "heldout_residual_band_27000_power": 0.00304194937150677, + "heldout_residual_band_675000_power": 0.07681375917338087, + "heldout_residual_band_1000000_power": 0.11305538222420118, + "heldout_residual_matched_power": 0.9157792365512673, + "effective_signal_to_residual_db": -3.639929333248138 + } + }, + { + "label": "A2", + "symbol_rate": 20000, + "raw_rx": { + "samples": 1638400, + "mean_i": 1.000250244140625, + "mean_q": 2.0000390625, + "power_code2": 7.5943505859375, + "ac_power_code2": 2.5936937835082423, + "rms_code": 2.755784931001964, + "peak_magnitude_code": 7.211102550927978, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 8.355127015785026, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.000379717529296875, + "band_27000_power": 1.7263462989934586, + "band_675000_power": 1.7983862355807485, + "power_standard_error": 0.03961683202831068 + }, + "local_zero_iq_background_windows": [ + { + "samples": 480000, + "mean_i": 0.9989791666666666, + "mean_q": 2.00009375, + "power_code2": 5.883064583333334, + "ac_power_code2": 0.8847301991102432, + "rms_code": 2.4255029547154408, + "peak_magnitude_code": 5.0990195135927845, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.45369731942485, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.00029415322916666667, + "band_27000_power": 0.0030190450807723868, + "band_675000_power": 0.07463668207172841, + "power_standard_error": 0.0009021263608471298 + }, + { + "samples": 480000, + "mean_i": 1.0004854166666666, + "mean_q": 2.0000104166666666, + "power_code2": 5.883220833333334, + "ac_power_code2": 0.8822080975954867, + "rms_code": 2.425535164315977, + "peak_magnitude_code": 5.830951894845301, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 7.6186376661535915, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.0002941610416666667, + "band_27000_power": 0.003053650977045963, + "band_675000_power": 0.073961606327725, + "power_standard_error": 0.0012067695631605175 + } + ], + "background_power": 0.8834691483528649, + "background_subtracted_raw": 1.7102246351553774, + "background_subtracted_uncertainty": 0.03964405579856132, + "background_subtracted_stable": true, + "background_subtracted_signal_power": 1.7102246351553774, + "channel_gain_complex": { + "real": 0.01755314566236957, + "imag": -0.02199755973474973, + "phase_rad_at_active_start": -0.8973012782222721 + }, + "channel_gain_power": 0.0007920055569282462, + "measurement": { + "frame": 1, + "start": 9803485, + "alignment_adjustment": -3, + "rx_active": { + "samples": 1638400, + "mean_i": 1.000250244140625, + "mean_q": 2.0000390625, + "power_code2": 7.5943505859375, + "ac_power_code2": 2.5936937835082423, + "rms_code": 2.755784931001964, + "peak_magnitude_code": 7.211102550927978, + "max_abs_i": 5.0, + "max_abs_q": 6.0, + "papr_db": 8.355127015785026, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.000379717529296875 + }, + "cfo_hz": 0.19617739757807567, + "gain_abs": 0.02814259328719097, + "dc_i": 1.0004532662364058, + "dc_q": 2.0003859700871685, + "train_signal_power": 1.5494089856585476, + "train_residual_power": 0.9895407718712785, + "train_actual_ac_power": 2.5389497575298265, + "train_cross_power": 4.0495384823202584e-16, + "heldout_signal_power": 1.548999768607681, + "heldout_residual_power": 0.8941535479569137, + "heldout_actual_ac_power": 2.6484381326123456, + "heldout_cross_power": 0.20528481604775145, + "heldout_residual_band_27000_power": 0.009765782070021769, + "heldout_residual_band_675000_power": 0.08171891866368976, + "heldout_residual_band_1000000_power": 0.1177276686242853, + "heldout_residual_matched_power": 3.3724974710374163, + "effective_signal_to_residual_db": 2.3863924873600086 + } + }, + { + "label": "B2", + "symbol_rate": 500000, + "raw_rx": { + "samples": 1638400, + "mean_i": 0.9994140625, + "mean_q": 1.999407958984375, + "power_code2": 6.305787353515625, + "ac_power_code2": 1.3093266987428072, + "rms_code": 2.511132683375298, + "peak_magnitude_code": 5.830951894845301, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 7.317395958495091, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.261157470703125e-05, + "band_27000_power": 0.023440988618055048, + "band_675000_power": 0.5015327722551061, + "power_standard_error": 0.009843366386499481 + }, + "local_zero_iq_background_windows": [ + { + "samples": 480000, + "mean_i": 1.0004854166666666, + "mean_q": 2.0000104166666666, + "power_code2": 5.883220833333334, + "ac_power_code2": 0.8822080975954867, + "rms_code": 2.425535164315977, + "peak_magnitude_code": 5.830951894845301, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 7.6186376661535915, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.1766441666666666e-05, + "band_27000_power": 0.003053650977045963, + "band_675000_power": 0.073961606327725, + "power_standard_error": 0.0012067695631605175 + }, + { + "samples": 480000, + "mean_i": 0.9988083333333333, + "mean_q": 1.9994125, + "power_code2": 5.878066666666666, + "ac_power_code2": 0.8827982347743042, + "rms_code": 2.4244724512080285, + "peak_magnitude_code": 5.0990195135927845, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.457388406130481, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.1756133333333333e-05, + "band_27000_power": 0.0029587129864172557, + "band_675000_power": 0.07444268200354834, + "power_standard_error": 0.0016031313210695718 + } + ], + "background_power": 0.8825031661848954, + "background_subtracted_raw": 0.4268235325579117, + "background_subtracted_uncertainty": 0.009898762952718625, + "background_subtracted_stable": true, + "background_subtracted_signal_power": 0.4268235325579117, + "channel_gain_complex": { + "real": 0.012227408500259825, + "imag": -0.006958453432916718, + "phase_rad_at_active_start": -0.517378791591959 + }, + "channel_gain_power": 0.00019792959281029668, + "measurement": { + "frame": 1, + "start": 12258685, + "alignment_adjustment": -3, + "rx_active": { + "samples": 1638400, + "mean_i": 0.9994140625, + "mean_q": 1.999407958984375, + "power_code2": 6.305787353515625, + "ac_power_code2": 1.3093266987428072, + "rms_code": 2.511132683375298, + "peak_magnitude_code": 5.830951894845301, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 7.317395958495091, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 1.261157470703125e-05 + }, + "cfo_hz": 0.20036016971332649, + "gain_abs": 0.014068745246477977, + "dc_i": 1.0007268354608458, + "dc_q": 1.9995225464921158, + "train_signal_power": 0.3833832641867325, + "train_residual_power": 0.9125567848168452, + "train_actual_ac_power": 1.2959400490035784, + "train_cross_power": 3.459732500488144e-16, + "heldout_signal_power": 0.3833787170249446, + "heldout_residual_power": 0.8881519217870418, + "heldout_actual_ac_power": 1.3227168214883227, + "heldout_cross_power": 0.051186182676336164, + "heldout_residual_band_27000_power": 0.003087916076869909, + "heldout_residual_band_675000_power": 0.0766452188649128, + "heldout_residual_band_1000000_power": 0.11237262287689712, + "heldout_residual_matched_power": 0.9135235192972193, + "effective_signal_to_residual_db": -3.648592601804231 + } + } + ], + "pairs": [ + { + "pair": 1, + "received_power_difference_db": -6.05021438090514, + "channel_gain_difference_db": -6.014143555521402, + "matched_component_difference_db": -6.056202112316672, + "matched_component_symbol_energy_difference_db": -20.035602199037047 + }, + { + "pair": 2, + "received_power_difference_db": -6.028048021201634, + "channel_gain_difference_db": -6.022174975174189, + "matched_component_difference_db": -6.06423353196946, + "matched_component_symbol_energy_difference_db": -20.04363361868984 + } + ], + "comparison_summary": { + "repeatability": [ + { + "comparison": "A2/A1", + "raw_rx_power_difference_db": -0.0012085532551280598, + "background_difference_db": -0.0017255178918689754, + "received_power_difference_db": -0.005652782408264756, + "channel_gain_difference_db": -0.0023081300526506692, + "matched_component_difference_db": -0.00230813005264874 + }, + { + "comparison": "B2/B1", + "raw_rx_power_difference_db": 0.0016044036249902335, + "background_difference_db": -0.011492673362299905, + "received_power_difference_db": 0.016513577295241087, + "channel_gain_difference_db": -0.0103395497054386, + "matched_component_difference_db": -0.010339549705438118 + } + ], + "averaging": "RATIO_OF_MEAN_LINEAR_POWERS_B1_B2_OVER_A1_A2", + "received_power_difference_db": -6.039124271880495, + "channel_gain_difference_db": -6.018156341674954, + "energy_per_symbol_difference_db": -20.01852435860087, + "energy_basis": "BACKGROUND_SUBTRACTED_RECEIVED_POWER_DIVIDED_BY_SYMBOL_RATE" + }, + "outside_waveform_background": [ + { + "start": 3309216, + "samples": 400000, + "mean_i": 0.9997525, + "mean_q": 2.0, + "power_code2": 5.8853875, + "ac_power_code2": 0.8858824387437494, + "rms_code": 2.4259817600303593, + "peak_magnitude_code": 5.385164807134504, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.926229353802586, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.000294269375, + "band_27000_power": 0.00300239645688663, + "band_675000_power": 0.07464470494185707, + "power_standard_error": 0.001189001018090443 + }, + { + "start": 15097760, + "samples": 400000, + "mean_i": 1.00201, + "mean_q": 1.9998775, + "power_code2": 5.8860125, + "ac_power_code2": 0.8824784448937502, + "rms_code": 2.4261105704398553, + "peak_magnitude_code": 5.0990195135927845, + "max_abs_i": 4.0, + "max_abs_q": 5.0, + "papr_db": 6.451521679042596, + "clipped_components_fraction": 0.0, + "clipped_samples_fraction": 0.0, + "symbol_energy_code2_seconds": 0.000294300625, + "band_27000_power": 0.002877436011683443, + "band_675000_power": 0.07431026562360402, + "power_standard_error": 0.0010078630955450837 + } + ], + "background_note": "Внутренние gaps: нулевой цифровой IQ при работающем TX; это не RF OFF. Внешние окна также требуют сверки времён запуска/остановки по журналам.", + "power_units": "RX code squared, not calibrated watts/dBm", + "residual_note": "Шум и неописанные моделью искажения; RX не нормируется для выравнивания A/B", + "synthetic": true, + "source_result_preserved": "software_minus6db.json" +} diff --git a/docs/LABS_INDEX.md b/docs/LABS_INDEX.md index 0dfe99a..3bc14d1 100644 --- a/docs/LABS_INDEX.md +++ b/docs/LABS_INDEX.md @@ -406,6 +406,51 @@ - **Далее:** STOP. Отдельное согласование измерительной схемы и допустимой частоты; усилитель не назначен, Git add/commit/push/pull/fetch не выполнялись. +## Lab056 — подготовка одного эфирного ABAB, 20 и 500 ксимв/с + +- **База:** Lab055 зафиксирована коммитом + `5add95ecb8865f59075bbbced08d97b183fb3b48`, только её семь файлов; без push. +- **Подготовлено:** один PRBS7/BPSK/RRC TX-файл ABAB, 1,323568 с; + Fs 8 Мвыб/с, цифровая несущая +50 кГц. RMS A/B 44,004413/44,001925 код, + разница мощности −0,000491 дБ; клиппинг 0. RX планируется на 3 с. +- **Проверено программно:** известные разницы усиления 0 и −6,020600 дБ + восстановлены с ошибкой менее 0,3 дБ в обеих парах. Анализируются отдельно + принятая мощность, фон, коэффициент передачи, остаток, спектр и энергия символа. +- **Проверки:** 34 целевых теста; quick_gate 857/30/13 PASS, + pytest 857 passed, 0 failed; verifier без остаточных находок; diff check PASS. +- **Граница:** пользователь выбрал эфир; частота/полоса и геометрия пока + не согласованы. 1400 МГц для излучения не используется. Общий такт проверен + только mock-вызовами; аппаратный preflight NOT_PERFORMED. RF TX=0. + Эфирный результат будет характеризовать весь путь с антеннами и распространением. +- **Отчёт:** [состояние](lab056_current_state.md), + [подготовка TX](../data/processed/lab056/preparation.json), + [сводка проверок](../data/processed/lab056/acceptance.json), журнал 047. +- **Далее:** STOP и отдельное разрешение на согласованный RF-сеанс. + Lab056 не коммитилась, push не выполнялся; Lab054 NOT_A сохранён. +- **Корректировка, запись 048:** кабельный контроль отложен из-за отсутствия + SMA-переходника; принят контролируемый OTA. RF_FREQ задаёт пользователь, + страна и границы диапазона не запрашиваются. Конкретная частота пока UNKNOWN. + Добавлен отдельный RX-only preflight с STOP перед разрешением TX, проверки + клиппинга до/после передачи, вывод комплексного h и повторов A2/A1, B2/B1. + TX и прежние результаты сохранены. 44 целевых теста; quick_gate 867/30/13 + PASS, pytest 867 passed; verifier без находок. Аппаратных команд нет, RF TX=0. + [Сводка корректировки](../data/processed/lab056/ota_correction.json). +- **Аппаратный preflight, запись 049:** пользователь задал 1400000000 Гц + только для Lab056, OTA LOS примерно 3–5 м. Common clock PASS: оба reg29 + 0x26, SLAVE CLKIN DETECTED. RX-only 800 000 отсчётов/0,1 с, overruns 0, + клиппинг 0, RMS 2,203153 код. CLKOUT выключены, процессы CLEAR, RF TX=0. + [Отчёт preflight](lab056_rx_preflight.md). STOP до отдельного разрешения TX. +- **Единственный ABAB, запись 050:** после отдельного разрешения один TX + 1,323568 с и RX 3 с; 4/4 сегмента, ошибка согласования начал ≤1 отсчёта, + клиппинг/overruns/underruns 0. X=+0,108895 дБ, Y=−0,163042 дБ, + Z=−13,870505 дБ. Повтор мощности A2/A1 −0,482024 дБ, B2/B1 −0,512676 дБ; + повтор коэффициента передачи примерно −0,18 дБ у обоих режимов. + Прежний провал 15,41 дБ в этой OTA-сессии не воспроизвёлся; собственные + потери HackRF не изолированы. Verifier подтвердил сырые данные и расчёты. + [RF-отчёт](lab056_rf_result.md), [сводка](../data/processed/lab056/rf_result.json), + [график](../data/processed/lab056/rf_overview.png). Выполненных TX 1, сейчас + RF TX=0, повторов нет. STOP, Lab056 не коммитилась, push не выполнялся. + ## Правило хранения данных Большие записи IQ, потоки `cs8`, бинарные объекты и другие аппаратные исходные diff --git a/docs/lab056_current_state.md b/docs/lab056_current_state.md new file mode 100644 index 0000000..1616cef --- /dev/null +++ b/docs/lab056_current_state.md @@ -0,0 +1,326 @@ +# Lab056 — подготовка сравнения 20 и 500 ксимв/с в одной сессии + +Подготовка 9 сентября 2026 года; корректировка OTA 10 сентября 2026 года. +Lab056 завершила единственный разрешённый OTA ABAB-сеанс 10 сентября. +Принятая мощность B/A +0,108895 дБ, коэффициент передачи по мощности +−0,163042 дБ, энергия символа −13,870505 дБ. Прежний провал 15,41 дБ +не воспроизвёлся. [Полный RF-отчёт](lab056_rf_result.md). +Выполненных передач 1, повторов 0; **RF TX сейчас = 0, STOP**. +Ниже сохранено описание этапов подготовки и preflight; актуальный итог +приведён в RF-отчёте и в заключительном блоке состояния. + +Простыми словами: для будущего опыта создан файл, который дважды чередует +медленную и быструю передачу с практически одинаковой цифровой амплитудой. +Анализатор на искусственных записях различает равное усиление и падение на 6 дБ. +Как изменятся полезный принятый сигнал и фон между A/B в реальном эфире, +ещё не измерено; пока записан только RX-фон без TX. +Одинаковый TX VGA и одинаковая цифровая мощность не доказывают одинаковую +мощность на выходе HackRF. Для абсолютных ватт/dBm нужен калиброванный прибор. + +## Зафиксированная база и границы задания + +По новому явному разрешению пользователя создан коммит Lab055: + +`5add95ecb8865f59075bbbced08d97b183fb3b48` + +`Lab055: audit received signal energy across symbol rates` + +В коммите ровно семь файлов: анализатор и тесты Lab055, её отчёт, два JSON +результата, только запись 046 журнала и только раздел Lab055 индекса. +Предшествующие незакоммиченные изменения Lab054 сохранены в рабочем каталоге. +Перед коммитом quick_gate: 823 теста, 28 функциональных проверок, 13 штатных +пропусков; pytest: 823 passed, 0 failed. Push не выполнялся. + +Lab055 установила почти равную цифровую мощность активного TX +(1950,308/1950,598 код²), снижение согласованной RX-компоненты на 15,413 дБ +и сопоставимый фон в одинаковой полосе. Разные аппаратные сессии не позволяют +приписать это снижение одной скорости. Lab054 остаётся **NOT_A, 0/16**. +Повторно проверены все 34 SHA-256 входов Lab055: изменений нет. + +Пользователь осознанно изменил методику: необходимого SMA-переходника нет, +поэтому сейчас выполняется подготовка контролируемого эфирного ABAB. +Кабельный контроль TX → 30 дБ → RX отложен до получения переходника +и будет отдельной проверкой, без автоматического запуска после Lab056. + +Схема: MASTER TX → TX-антенна → свободное пространство → RX-антенна → SLAVE RX. +На всю ABAB сохраняются антенны, кабели, одинаковая поляризация, расстояние, +ориентация, положение оборудования, частота, усиления и common clock. +Антенны не трогают; по возможности исключают движение людей возле них. +Внешние PA и LNA, в том числе TQP3M9037, не используются. + +`RF_FREQ = USER_AUTHORIZED_RF_HZ = 1400000000`: значение сообщил пользователь. +Частоту, разрешённую для лаборатории, определяет пользователь. Страна и +границы национальных диапазонов больше не являются обязательными полями +runner; повторное исследование национальной регуляторики не проводилось. +1400 МГц не подставляется по умолчанию. Mock-значения 915/916 МГц также +не являются выбором частоты для аппаратного опыта. + +| Параметр эфирной схемы | Текущее значение | +|---|---| +| Центральная RF-частота | 1400000000 Гц, только лабораторная Lab056 | +| TX-антенна / RX-антенна | Имеющиеся антенны 1400 МГц по описанию пользователя; модели/маркировка не сообщены | +| Расстояние TX–RX | Примерно 3–5 м по заданию; точное измерение не сообщено | +| Взаимная ориентация и поляризация | Одинаковые, антенны неподвижны, по заданию пользователя | +| Прямая видимость LOS / отсутствие прямой видимости NLOS | LOS | + +После конкретного RF_FREQ выполнен аппаратный RX-only preflight, PASS. +Сейчас STOP. TX — только после отдельного разрешения на один ABAB-сеанс. +Само сообщение частоты не является разрешением на TX. Частота 1400 МГц +не назначена рабочей частотой SDR_Rover: ориентир около 180 МГц и варианты +50/144 МГц рассматриваются отдельно, вне Lab056. + +## Подготовленный TX + +Файл: `data/raw/lab056/tx_abab.cs8`, signed int8 IQ, 21 177 088 байт. +SHA-256: `5b34bbe1a8e6d037d2d6d367a74e9eb84e8940db7da61600ffaa7f7497d4f600`. +Параметры сохранены в `data/raw/lab056/tx_metadata.json` и +[preparation.json](../data/processed/lab056/preparation.json). + +Используются прежние PRBS7, BPSK и RRC из тракта Lab043/Lab042: +roll-off 0,35, span 10 символов, защитные участки по 16 символов. +Fs = 8 000 000 комплексных отсчётов/с, цифровая несущая +50 кГц. +Алгоритмы PHY/FEC/CRC, пороги и штатный приёмник не изменялись. + +| Параметр | A: 20 ксимв/с | B: 500 ксимв/с | +|---|---:|---:| +| Отсчётов на символ | 400 | 16 | +| Полезных PRBS7-символов | 4096 | 102400 | +| Длительность активных символов | 0,204800 с | 0,204800 с | +| Длительность сегмента с защитными участками | 0,206900 с | 0,204884 с | +| RMS всего сегмента после int8 | 44,004413 код | 44,001925 код | +| Средняя мощность всего сегмента | 1936,388382 код² | 1936,169379 код² | +| RMS активного участка | 44,227281 код | 44,010867 код | +| Средняя мощность активного участка | 1956,052408 код² | 1936,956395 код² | +| Клиппинг | 0 | 0 | + +Разница средней мощности B/A всего сегмента: **−0,000491 дБ**, +критерий подготовки |разница| ≤ 0,01 дБ выполнен. Активные участки отличаются +на −0,042606 дБ из-за разной доли защитных участков; это явно сохранено +в метаданных и учитывается при сравнении коэффициента передачи. +RMS указан в кодах, средняя мощность — RMS² в код². + +Последовательность: gap → A1 → gap → B1 → gap → A2 → gap → B2 → gap. +Каждый gap длится 0,1 с. A1 и A2 совпадают побайтно; B1 и B2 тоже. +Один файл содержит 10 588 544 комплексных отсчёта, **1,323568 с**. +План RX: 24 000 000 отсчётов, **3 с**, запуск на 0,5 с раньше TX. + +Важно: gap — нулевые цифровые IQ при работающем TX-процессе. +Это не выключение передатчика; утечка несущей и собственный фон возможны. +Полная длительность файла включает эти участки. + +## Измерения сохранённого RX + +Анализатор `experiments/lab056_abab_energy.py` сначала ищет всю ABAB +корреляцией с известным TX: шаг 32 отсчёта, сетка остаточного частотного +смещения (CFO) от −2 до +2 Гц с шагом 0,25 Гц. Затем существующий метод +Lab055 уточняет задержку, CFO, фазу, постоянное смещение и комплексный +коэффициент на обучающих плитках; мощность компоненты и остатка проверяется +на отдельных плитках. При недостаточном совпадении результат UNKNOWN. +Порог 0,05 относится только к этой диагностической локализации; +он не меняет пороги PHY/CRC и не даёт независимого приёма пакетов. + +Прореживание без фильтра используется только при грубом поиске. Мощности +и спектры вычисляются по исходным полным отсчётам. RX не масштабируется +для искусственного выравнивания A/B. + +Для каждого A1/B1/A2/B2 сохраняются: + +- Полная средняя IQ-мощность `mean(|r|²)` и мощность после удаления среднего + (AC), RMS, постоянное смещение, пик и клиппинг. +- Два ближайших окна фона по 60 мс в соседних нулевых цифровых участках. + Дополнительно — доступные окна по 50 мс вне всей последовательности. + Внешние окна нельзя автоматически назвать RF OFF без проверки времён + запуска/остановки: в текущей подготовке аппаратного фона ещё нет. +- Разность AC-мощности и среднего локального фона. Разброс оценивается + по неперекрывающимся блокам 4 мс, включая отличие фона до и после сегмента. + Если превышение не больше трёх оценок неопределённости, итоговая мощность + полезного сигнала `null`, а исходная разность сохраняется. Это критерий + численной устойчивости, не калиброванный доверительный интервал. +- Комплексный коэффициент `h = sum(conj(s)*r) / sum(|s|²)` после согласования + и удаления постоянного смещения; сравнивается `|h|²`. +- Мощность согласованной компоненты и остатка. Остаток включает шум и + искажения, которые не описывает модель; это не чистый тепловой шум. +- Интегральная мощность спектра Welch в полосах 27 и 675 кГц вокруг + +50 кГц. Для A штатная полоса 27 кГц, для B — 675 кГц; + обе полосы записываются также для сравнения фона в одинаковых условиях. + +Отдельно для двух пар сохраняются B/A в дБ по принятой мощности после +вычитания фона, по `|h|²`, по согласованной компоненте и по её энергии +символа `P/Rs`. Единицы мощности — коды RX², энергии — код²·с; +это относительные цифровые оценки, не калиброванные ватты и джоули. +При одинаковой принятой мощности рост скорости в 25 раз даст уменьшение +энергии символа на 13,9794 дБ. Равенство принятой мощности сначала проверяется. + +Корректировка добавляет явный вывод `h.real`, `h.imag` и фазы относительно +начала активного участка. Он вычисляется на тех же обучающих плитках +при уже найденном CFO; его модуль проверяется на совпадение с моделью +Lab055. Алгоритм согласования и разделение обучения/проверки сохранены. + +Отдельно выводятся A2/A1 и B2/B1: полная raw-мощность, фон, полезная +мощность после вычитания фона, `|h|²` и согласованная компонента. +Итоговые X/Y/Z в `comparison_summary` используют отношение средних +линейных мощностей двух B к двум A. X — полезная принятая мощность +после вычитания фона, Y — `|h|²`, Z — энергия символа этой же полезной +мощности. Если вычитание фона неустойчиво хотя бы в одном сегменте, +X/Z остаются `null`; компонентные метрики и повторяемость сохраняются. + +## Проверка искусственными записями + +Созданы две явно синтетические записи CS8 по 3 с: одинаковое усиление +обоих режимов и уменьшение амплитуды B вдвое (мощность −6,020600 дБ). +В модель добавлены шум, постоянное смещение, CFO +0,2 Гц, фаза и неизвестное +для поиска начало 4 160 013 отсчётов. Известное начало записано в результат +после анализа и не передавалось алгоритму поиска. + +| Вход модели | Пара | Разница принятой мощности B/A | Разница `|h|²` B/A | Разница энергии согласованной компоненты | +|---|---:|---:|---:|---:| +| Одинаковое усиление | 1 | −0,051497 дБ | +0,001786 дБ | −14,019673 дБ | +| Одинаковое усиление | 2 | −0,041310 дБ | −0,002894 дБ | −14,024352 дБ | +| B: −6,020600 дБ | 1 | −6,050214 дБ | −6,014144 дБ | −20,035602 дБ | +| B: −6,020600 дБ | 2 | −6,028048 дБ | −6,022175 дБ | −20,043634 дБ | + +Обе проверки PASS: ошибка коэффициента передачи в каждой паре меньше +заданных 0,3 дБ. Разница принятой мощности включает небольшое различие +цифровой мощности активных участков. Это результаты модели, не RF Lab056. +Данные: [равное усиление](../data/processed/lab056/software_equal.json), +[ослабление B](../data/processed/lab056/software_minus6db.json). + +При корректировке те же сохранённые IQ проанализированы без перегенерации. +Прежние файлы результатов сохранены; новые сводки: +[равное усиление, OTA summary](../data/processed/lab056/software_equal_ota_summary.json), +[ослабление B, OTA summary](../data/processed/lab056/software_minus6db_ota_summary.json). + +| Искусственная запись | X: мощность B/A | Y: коэффициент передачи B/A | Z: энергия символа B/A | Повтор `|h|²`, A2/A1 | Повтор `|h|²`, B2/B1 | +|---|---:|---:|---:|---:|---:| +| Равное усиление | −0,046404 дБ | −0,000553 дБ | −14,025804 дБ | −0,002308 дБ | −0,006988 дБ | +| B: −6,020600 дБ | −6,039124 дБ | −6,018156 дБ | −20,018524 дБ | −0,002308 дБ | −0,010340 дБ | + +Это по-прежнему результаты программной модели. Они не устанавливают +величину эфирного различия Lab056. + +Повторный анализ существующего файла с новым именем результата: + +```powershell +python experiments/lab056_abab_energy.py analyze --rx data/raw/lab056/synthetic_equal.cs8 --output data/processed/lab056/recheck_equal.json +``` + +Существующие выходные файлы не перезаписываются. Команды `prepare` и +`software` создают данные только при отсутствии соответствующих файлов. + +## Подготовка однократного аппаратного запуска + +`experiments/lab056_capture_runner.py` не имеет аппаратного CLI. Без конкретного +положительного целого RF_FREQ из задания пользователя аппаратные действия +не начинаются. Частота одинакова для всех RX-команд и единственной TX-команды; +цифровая несущая остаётся +50 кГц. Страна/регуляторная полоса не запрашиваются +программой. Геометрия сохраняется вместе с частотой в отдельном OperatingPoint. + +Роли плат сохранены: MASTER/TX `000000000000000097c063dc323b97d3`, +SLAVE/RX `000000000000000097c063dc2e5327d3`. Планируется прежнее тактирование +10 МГц TCXO → MASTER → CLKOUT → SLAVE CLKIN. Требуются оба reg29 = 0x26 +и SLAVE CLKIN = DETECTED после короткого RX-start. Сначала логика проверена +mock-вызовами; теперь эти значения подтверждены аппаратным preflight. + +Вызов `preflight_only` после получения RF_FREQ проверит инвентаризацию, +common clock и сохранит 0,1 с RX без TX на заданной частоте при RX 24/24 дБ. +Он проверит размер, явный нулевой счётчик потерь, уровень и клиппинг, +запишет `preflight_result.json`, выключит CLKOUT и завершится с STOP. +Любая TX-команда внутри этого этапа запрещена обёрткой runner. +Файл попытки создаётся эксклюзивно; автоматического повтора нет. + +После отдельного разрешения `capture_once` потребует PASS preflight той же +частоты, геометрии и SHA TX. Поскольку после preflight CLKOUT выключены, +перед фактическим сеансом опора проверяется заново при запуске. Это проверка +готовности перед единственным TX, а не повтор передачи. + +TX VGA 10 дБ, RX LNA/VGA 24/24 дБ, RF amplifier и Bias-Tee OFF, +Fs 8 Мвыб/с фиксированы на всю ABAB. RX запускается первым; затем допускается +один TX-процесс с конечным числом отсчётов, без `-R`. Маркер попытки создаётся +эксклюзивно; ошибка расходует попытку, автоматического повтора нет. +Требуются процессы CLEAR до/после, правильный размер RX, явные нулевые +RX overruns/TX underruns и успешное выключение CLKOUT обеих плат. +После упреждения RX проверяются последние 65 536 записанных отсчётов: +при rail-кодах −128/127 TX не запускается, RF TX=0 и STOP. Полная запись +проверяется также после ABAB. Если клиппинг появился только при передаче, +фиксируется RF TX=1 и невалидное измерение без повтора. Уже выполненная +передача не переобозначается нулём. В отчёте сохраняются RMS, пики I/Q, +доли клиппинга; отсутствие rail-кодов само по себе не доказывает отсутствие +аналоговой компрессии. Gain не меняется автоматически ни в одном сценарии. +Аппаратные помощники переиспользованы из существующей Lab054; её файлы +`experiments/lab054_hardware_control.py` и `tools/hackrf_process_check.py` +включаются в фиксацию Lab056 как необходимые зависимости вместе с их +двумя тестовыми файлами. Без них runner Lab056 не импортируется в чистой +копии репозитория, что независимо воспроизведено verifier. Старые отчёты, +данные и записи журнала Lab054 в эту фиксацию не входят. Реализации +зависимостей не переписывались; аппаратная логика осталась проверенной. + +Verifier независимо подтвердил SHA/размеры TX, нулевые gaps, побайтную +повторяемость A/B и пересчитал коэффициенты передачи вторым методом. +Он воспроизвёл ошибку разбора журнала `1 RX overruns\n0 overruns`; +исправленный разбор отклоняет ненулевые, неизвестные и неразобранные +счётчики. Повторные mock-вызовы `capture_once` закрыли находку. +Остаточных воспроизведённых находок нет. Оборудование verifier не использовал. + +Исходная подготовка: 34 целевых теста passed; quick_gate: 857 тестов, +30 функциональных проверок, 13 штатных пропусков, PASS. Полный pytest: +857 passed, 0 failed, 96,50 с (кеш отключён из-за прежнего отказа доступа). +`git diff --check`: PASS. Машинная сводка: +[acceptance.json](../data/processed/lab056/acceptance.json). + +Корректировка OTA: 44 целевых теста PASS; quick_gate 867 тестов / +30 функциональных проверок / 13 штатных пропусков, PASS; pytest +867 passed, 0 failed, 89,32 с. Verifier исполнил все 44 сценария +в памяти без файлов и оборудования; остаточных находок нет. +Новая сводка [ota_correction.json](../data/processed/lab056/ota_correction.json) +дополняет исходную acceptance, не заменяя исторические 857 passed. + +## Как читать будущий эфирный результат + +Эфирный ABAB сравнит весь путь: TX, антенны, распространение, RX. Малое +различие означает, что большой провал не воспроизведён в этом пути и этой +сессии. Оно не доказывает равенство мощности непосредственно на выходе TX. +Большое повторяемое различие тоже нельзя автоматически отнести внутрь +HackRF: частотная избирательность антенн и многолучевого распространения +остаётся частью измерения. Для отделения аппаратного эффекта пригодится +отдельно согласованный кабельный или калиброванный измерительный опыт. + +Ни необходимость PA, ни изменение результатов Lab047/Lab054 из этой +подготовки не следуют. Архитектура проекта сохраняется: управление через +RadioMaster/ExpressLRS/CRSF, SDR — видеотракт с целью минимум 5 свежих кадров/с. + +## Состояние перед STOP + +```text +LAB055 COMMIT = 5add95ecb8865f59075bbbced08d97b183fb3b48 +NEW HEAD = 5add95ecb8865f59075bbbced08d97b183fb3b48 +LAB056 RESULT = OTA_ABAB_VALID_LARGE_DROP_NOT_REPRODUCED_STOP +PHYSICAL CONNECTION = OTA, LOS, fixed antennas, same polarization/orientation, approximately 3-5 m per user +RF FREQUENCY = 1400000000 Hz (Lab056 test only) +A SYMBOL RATE = 20 ksymbol/s +B SYMBOL RATE = 500 ksymbol/s +TX RMS A = 44.004413 code +TX RMS B = 44.001925 code +TX POWER DIFFERENCE B/A = -0.000491 dB (whole segment) +ABAB TX DURATION = 1.323568 s +RX PLANNED DURATION = 3 s, lead 0.5 s +COMMON CLOCK PREFLIGHT = HARDWARE PASS, both reg29=0x26, SLAVE CLKIN=DETECTED +RX PREFLIGHT = PASS, 800000 complex samples, 0.1 s, overruns=0 +CLIPPING = 0 +READY FOR ANOTHER TX = NO (authorized single attempt consumed) +COMPLETED TX SESSIONS = 1 +AUTOMATIC TX REPEATS = 0 +RX ABAB RECORD = 24000000 complex samples, 3 s, clipping=0, overruns=0 +TX UNDERRUNS = 0 +RECEIVED POWER DIFFERENCE B/A = +0.108895 dB +TX-MATCHED CHANNEL GAIN DIFFERENCE B/A = -0.163042 dB +ENERGY PER SYMBOL DIFFERENCE = -13.870505 dB +BASELINE pytest = 857 passed (сохранённый результат подготовки) +quick_gate = PASS, 867 tests / 30 functional / 13 skipped +pytest = PASS, 867 passed / 0 failed (после корректировки) +git diff --check = PASS +RF TX = 0 +LAB056 COMMIT = NOT_PERFORMED +PUSH = NOT_PERFORMED +CURRENT SINGLE-TX AUTHORIZATION = CONSUMED +STOP +``` diff --git a/docs/lab056_rf_result.md b/docs/lab056_rf_result.md new file mode 100644 index 0000000..5e6ee37 --- /dev/null +++ b/docs/lab056_rf_result.md @@ -0,0 +1,222 @@ +# Lab056 — единственный OTA ABAB: результат + +10 сентября 2026 года, сеанс 12:32:24–12:32:28 по Москве. + +**Внутри одного короткого эфирного сеанса большой провал при переходе +20 → 500 ксимв/с не воспроизвёлся.** Принятая мощность после вычитания фона +у B выше A на 0,109 дБ; согласованный коэффициент передачи по мощности +ниже на 0,163 дБ. Обе пары A/B дают близкие результаты. Энергия символа +уменьшилась на 13,871 дБ: при почти одинаковой принятой мощности она +приходится на в 25 раз большее число символов в секунду. + +Это результат всего OTA-пути с антеннами и распространением. Он не +измеряет выходные dBm HackRF и не объясняет задним числом причину прежнего +различия Lab047/Lab054 на 15,41 дБ. Lab054 остаётся **NOT_A, 0/16**. + +Выполнена ровно **одна** передача. Сейчас **RF TX = 0**, передатчик +остановлен; повторов нет. Разрешённая попытка израсходована. **STOP.** + +## Фактические условия + +Пользователь отдельно разрешил этот сеанс после аппаратного RX-only +preflight. Частота 1 400 000 000 Гц относится только к Lab056, не является +выбором рабочего диапазона SDR_Rover. Ориентир около 180 МГц и варианты +50/144 МГц рассматриваются отдельно и здесь не исследовались. + +OTA: MASTER TX → TX-антенна → LOS → RX-антенна → SLAVE RX. По заданию +пользователя антенны неподвижны, ориентация и поляризация одинаковы, +расстояние примерно 3–5 м, кабели не меняются. Использованы имеющиеся +антенны на 1400 МГц; модели/маркировка и точное измеренное расстояние +не сообщены. Программа не измеряет геометрию; это описание пользователя. + +Один сохранённый TX-файл содержит A1 → gap → B1 → gap → A2 → gap → B2 +с дополнительными начальным/конечным gaps. A = 20 ксимв/с, B = 500 ксимв/с. +Fs 8 Мвыб/с; цифровая несущая +50 кГц; прежние PRBS7/BPSK/RRC. +TX VGA 10 дБ, RX LNA/VGA 24/24 дБ, RF amplifier/Bias-Tee OFF. +Внешние PA/LNA отсутствуют. Частота, усиления, Fs и параметры формы +не менялись между сегментами. PHY/FEC/CRC, пороги и timing не изменялись. + +Цифровой RMS всего сегмента A/B: 44,004413/44,001925 код; +разница мощности B/A −0,000491 дБ. Разница активных частей −0,042606 дБ +из-за разной доли защитных участков сохранена в метаданных и не скрывается. +RX не нормировался для искусственного выравнивания A/B. + +## Полнота записи и аппаратные проверки + +| Проверка | Фактический результат | +|---|---| +| Число TX-процессов | 1, без `-R`, конечный `-n 10588544` | +| TX-файл | 21 177 088 байт, 10 588 544 комплексных отсчёта, 1,323568 с | +| Основной RX | 48 000 000 байт, 24 000 000 комплексных отсчётов, ровно 3 с | +| Порядок запуска | RX раньше TX на 0,517342 с по журналу запуска процессов | +| MASTER / SLAVE reg29 | 0x26 / 0x26 | +| SLAVE CLKIN | DETECTED в пределах штатного ожидания запуска опоры | +| RX overruns / TX underruns | 0 / 0 по всем явным счётчикам журналов | +| Клиппинг RX до TX | 0 / 65 536 отсчётов проверенного хвоста | +| Клиппинг полного RX после ABAB | 0 / 24 000 000 отсчётов; 0 / 48 000 000 компонент | +| Полный RX: RMS / максимумы абсолютных I,Q | 2,235380477 код / 5, 6 код | +| Процессы до / после | CLEAR / CLEAR | +| Завершение | CLKOUT обеих плат выключены, ошибок cleanup нет | + +Общая опора проверена при запуске заново, поскольку предыдущий preflight +завершился выключением CLKOUT. Первый запрос CLKIN ещё не обнаружил опору; +второй обнаружил её через 137,359 мс штатного ожидания. После PASS +состоялся единственный TX; опрос CLKIN не является повтором передачи. + +В журнале 14 команд: инвентаризация, опора, два коротких RX-start по +65 536 отсчётов для выбора опоры, один основной RX, один TX и cleanup. +После запуска TX до его окончания других аппаратных команд нет. +Параметры команд и их исходный вывод сохранены; аппаратной перестройки +между A/B не было. Физическая неподвижность антенн следует из заданных +пользователем условий, а не из программного измерения. + +Утилита указала TX transfer time 1,32538 с и RX transfer time 3,01535 с. +Это служебные интервалы обмена, отличные от длительности отсчётов файла; +они не используются вместо расчёта длительности по числу отсчётов и Fs. +Отсутствие rail-кодов не является калиброванной проверкой аналоговой +компрессии; обнаруженных цифровых признаков насыщения нет. + +## Все четыре сегмента + +Подготовленный анализатор нашёл ABAB с нормированной корреляцией 0,384366 +и грубым остаточным CFO 0 Гц. Оценённые начала всей последовательности +по отдельным сегментам: 4 454 791, 4 454 791, 4 454 790, 4 454 791 отсчёт. +Разброс составляет один отсчёт, 0,125 мкс. Все сегменты расположены +внутри RX, идут в правильном порядке и не перекрываются. + +| Сегмент | Начало сегмента, отсчёт RX | Начало, с | Конец, с | Активных отсчётов | +|---|---:|---:|---:|---:| +| A1 | 5 254 791 | 0,656848875 | 0,863748875 | 1 638 400 | +| B1 | 7 709 991 | 0,963748875 | 1,168632875 | 1 638 400 | +| A2 | 10 149 062 | 1,268632750 | 1,475532750 | 1 638 400 | +| B2 | 12 604 263 | 1,575532875 | 1,780416875 | 1 638 400 | + +Длительность активного участка каждого сегмента 0,2048 с. С защитными +участками A длится 0,2069 с, B — 0,204884 с. Межсегментные интервалы +составляют 0,1 с с расхождением не более одного отсчёта из-за согласования. +В спектрах A и B видны соответственно узкая и широкая полосы PRBS/BPSK. +Границы, ширина спектров и согласованные компоненты подтверждают +наличие четырёх сегментов; это диагностическое измерение с TX-эталоном, +не независимый приём пакетов. + +![Запись, мощности и спектры единственного ABAB](../data/processed/lab056/rf_overview.png) + +## Измерения A1/B1/A2/B2 + +Все мощности ниже — **код² RX**, не ватты/dBm. `h` выражает отношение +цифровых кодов RX/TX после согласования и удаления постоянного смещения. +Для вычитания фона используется AC-мощность — после удаления среднего, +поэтому она показана отдельно от RAW, включающего постоянную составляющую. + +| Метрика | A1 | B1 | A2 | B2 | +|---|---:|---:|---:|---:| +| RAW RX POWER, включая среднее | 5,303053589 | 5,328170166 | 5,311703491 | 5,396551514 | +| RX AC POWER, без среднего | 1,084963566 | 1,092709351 | 1,049867204 | 1,090638777 | +| BACKGROUND POWER, AC | 0,622282607 | 0,616699337 | 0,635792032 | 0,667630886 | +| BACKGROUND-SUBTRACTED SIGNAL POWER | 0,462680958 | 0,476010015 | 0,414075173 | 0,423007891 | +| Оценка неопределённости вычитания фона | 0,029702311 | 0,034542825 | 0,017352868 | 0,047227716 | +| TX-MATCHED COMPLEX GAIN h | −0,008543899 + j0,009310849 | −0,008089660 + j0,009397484 | −0,007000883 + j0,010205712 | −0,006710537 + j0,010126447 | +| Коэффициент передачи по мощности, abs(h)² | 0,000159690119 | 0,000153755289 | 0,000153168935 | 0,000147576238 | +| MATCHED SIGNAL COMPONENT POWER | 0,312320987 | 0,297815525 | 0,299566893 | 0,285847043 | +| RESIDUAL POWER | 0,821513728 | 0,884789710 | 0,782684444 | 0,880722972 | +| INTEGRATED SPECTRAL POWER, полоса 27 кГц | 0,347264323 | 0,029697350 | 0,335922975 | 0,030437417 | +| INTEGRATED SPECTRAL POWER, полоса 675 кГц | 0,508299262 | 0,512832243 | 0,500120185 | 0,533314850 | + +Полосы спектрального интегрирования центрированы на +50 кГц. Фактическая +расчётная полоса A — 27 кГц, B — 675 кГц; строка 675 кГц также даёт +сравнение в общей полосе. Спектральные интегралы включают фон. Различие +значений в полосе 27 кГц между A/B не является потерей полной мощности B: +большая часть широкого сигнала B лежит вне этой узкой полосы. + +Вычитание фона устойчиво во всех четырёх сегментах по заранее подготовленному +критерию: превышение больше трёх оценок неопределённости. Эта оценка учитывает +разброс блоков и отличие фона до/после, но не является калиброванным +доверительным интервалом. Фон берётся из ближайших нулевых цифровых gaps; +TX-процесс в них работает, поэтому gaps нельзя называть выключенным RF. +Отдельные внешние окна фона и их спектры сохранены в полном JSON. + +Комплексный h оценён на обучающих плитках; его фаза относится к началу +активного участка после коррекции CFO. Мощность согласованной компоненты +и остатка измерена на проверочных плитках. Остаток содержит шум и +неописанные моделью искажения. Поэтому он не равен отдельно измеренному +фону, а согласованная компонента не равна всей мощности после вычитания фона. +Полная RAW/AC-статистика относится ко всему активному участку; плиточные +метрики не следует складывать с ней как одну точную энергетическую сумму. + +## Повторяемость и итоговые X/Y/Z + +В таблице повторяемости знак относится ко **второму повтору относительно +первого**: A2/A1 и B2/B1, 10 log10 отношения мощностей. + +| Сравнение повторов | RAW RX | Фон AC | Полезная мощность после фона | abs(h)² | Согласованная компонента | +|---|---:|---:|---:|---:|---:| +| A1 / A2 REPEATABILITY: A2/A1 | +0,007078 дБ | +0,093274 дБ | −0,482024 дБ | −0,181074 дБ | −0,181074 дБ | +| B1 / B2 REPEATABILITY: B2/B1 | +0,055382 дБ | +0,344629 дБ | −0,512676 дБ | −0,178136 дБ | −0,178136 дБ | + +| Пара A/B | Принятая мощность B/A после фона | abs(h)² B/A | Согласованная компонента B/A | +|---|---:|---:|---:| +| B1/A1 | +0,123345 дБ | −0,164480 дБ | −0,206538 дБ | +| B2/A2 | +0,092693 дБ | −0,161543 дБ | −0,203601 дБ | + +Итоговые X/Y/Z — отношение средних **линейных** мощностей B1/B2 к A1/A2, +а не среднее значений в дБ. Z рассчитано из той же мощности после фона, +что X, с делением на скорость символов. Это энергия в код²·с, не джоули. + +```text +500K / 20K RECEIVED POWER DIFFERENCE = +0.108895 dB +500K / 20K TX-MATCHED CHANNEL GAIN DIFFERENCE = -0.163042 dB +ENERGY PER SYMBOL DIFFERENCE = -13.870505 dB +``` + +Расчёт Z: +0,108895 − 10 log10(500000/20000) = −13,870505 дБ. +Отдельная энергия согласованной компоненты в парных результатах изменилась +на −14,185938 и −14,183001 дБ; это другой числитель, её не подменяют Z. + +## Инженерная интерпретация + +1. Внутри этой сессии 20 и 500 ксимв/с дали почти равные мощности. Небольшое + различие повторилось в обеих парах; утверждать точную частотную + характеристику по двум повторам нельзя. +2. Вторые повторы слабее первых на 0,48/0,51 дБ по мощности после фона + и примерно на 0,18 дБ по коэффициенту передачи. Фон также немного + меняется и содержит кратковременные всплески; при этом относительное + сравнение B/A сохраняется: расхождение двух оценок X около 0,031 дБ, + двух оценок Y около 0,003 дБ. +3. Прежний провал порядка 15,41 дБ **не воспроизвёлся** в текущей короткой + OTA-сессии. Причина различия старых раздельных опытов остаётся + неустановленной; их результаты не пересматриваются. +4. По OTA нельзя объявить эффект собственной аппаратной потерей HackRF + Plus: антенны и распространение входят в измеренный путь. В этой + сессии большого эффекта вообще не обнаружено. Абсолютная мощность + на выходе передатчика не измерена. +5. Кабельный контроль после получения SMA-переходника остаётся необходимым + отдельным этапом для отделения свойств аппаратуры от антенн и канала. + OTA его не заменяет. Автоматического повторения опыта или добавления + PA/внешнего LNA нет; необходимость усилителя не установлена. + +## Проверка и артефакты + +Verifier независимо прочитал журналы и raw IQ без оборудования и записи +файлов: проверил число команд, постоянство параметров, опору, размеры, +SHA, отсутствие клиппинга/потерь и согласованность четырёх начал. Raw AC, +два окна фона, CFO и комплексный МНК пересчитаны вторым способом; +результаты совпали с анализатором до 1e−12. Воспроизведённых находок нет. + +RX SHA-256: `e336dd653fa554058052fcf851e9f2462f66b8cf7c710815ca2b9a09ffc23ad4`. +TX SHA-256: `5b34bbe1a8e6d037d2d6d367a74e9eb84e8940db7da61600ffaa7f7497d4f600`. + +- [Полный подготовленный анализ](../data/processed/lab056/rf_analysis.json). +- [Итоговая машинная сводка](../data/processed/lab056/rf_result.json). +- [Авторизация и фиксированные параметры](../data/processed/lab056/rf_session_authorization.json). +- [Фактические команды и время](../data/processed/lab056/rf_session_commands.json). +- Raw: `data/raw/lab056/rx_stream.cs8`, `capture_result.json`, + `hardware_attempt.json`, `tx_process_result.json`, `rx_stdout.txt`, `rx_stderr.txt`. + +Исходные результаты подготовки, preflight и искусственные записи сохранены. +Код анализатора/runner и TX не изменялись; использована проверенная версия +44 целевых теста / quick_gate 867/30/13 / pytest 867 passed. Для анализа +аппаратной записи полные тесты повторно не запускались. Diff check PASS. +HEAD `5add95ecb8865f59075bbbced08d97b183fb3b48`, Lab056 не коммитилась, +push не выполнялся. Приём пакетов, видео и FEC не проверялись. + +**Выполненных TX-сеансов: 1. RF TX сейчас = 0. STOP.** diff --git a/docs/lab056_rx_preflight.md b/docs/lab056_rx_preflight.md new file mode 100644 index 0000000..922ff8a --- /dev/null +++ b/docs/lab056_rx_preflight.md @@ -0,0 +1,98 @@ +# Lab056 — аппаратный common-clock и RX-only preflight + +10 сентября 2026 года, 12:16:28–12:16:29 по Москве. + +**Аппаратный preflight PASS. RF TX = 0. STOP перед отдельным разрешением TX.** +Проверена общая опора и записан фон при выключенном передатчике. +Сравнение A/B по эфиру ещё не выполнялось. + +```text +RF_FREQ = 1400000000 Hz +COMMON CLOCK = PASS; MASTER reg29=0x26; SLAVE reg29=0x26; SLAVE CLKIN=DETECTED +RX PREFLIGHT = PASS; 800000 complex samples; 0.1 s; RX overruns=0 +CLIPPING = 0 / 800000 samples (0%) +RF TX = 0 +READY FOR SINGLE ABAB TX = YES (technical preflight; separate authorization pending) +STOP +``` + +## Условия + +По заданию пользователя 1400 МГц — только частота текущего лабораторного +Lab056. Она не назначает рабочий диапазон SDR_Rover. Ориентир дальнейших +полевых работ около 180 МГц рассматривается отдельно; антенна на этот +диапазон уже имеется. Варианты 50/144 МГц здесь не исследуются. + +Схема задана пользователем: MASTER TX → TX-антенна → LOS → RX-антенна → SLAVE RX. +Используются имеющиеся антенны на 1400 МГц. Точные модели/маркировка не +сообщены и программно не установлены; они не являлись препятствием для +этого RX-only этапа. Антенны неподвижны, ориентация и поляризация одинаковы. +Расстояние по заданию примерно 3–5 м; точное измеренное значение отсутствует. +Кабели и геометрия сохраняются на будущую ABAB. + +Аппаратный RX: Fs 8 Мвыб/с, LNA/VGA 24/24 дБ, RF amplifier и Bias-Tee OFF. +Внешние PA/LNA не используются. TX VGA 10 дБ остаётся запланированным +параметром будущего сеанса; TX в этом этапе не включался. + +MASTER `000000000000000097c063dc323b97d3` и SLAVE +`000000000000000097c063dc2e5327d3` подтверждены свежей инвентаризацией. +Обе платы определены как HackRF One r9 с firmware/libhackrf 2024.02.1. + +## Что выполнено + +Перед оборудованием подтверждены HEAD, пустой Git index, SHA проверенного +кода и неизменность готового TX. Проверка процессов дала CLEAR. + +Выполнены короткие RX-start по 65 536 отсчётов на MASTER и SLAVE для выбора +источника тактирования, чтения reg29 обеих плат и SLAVE CLKIN. Оба reg29 +равны 0x26; CLKIN обнаружен первым запросом, через 67,787 мс после начала +ожидания опоры. Затем SLAVE записал 800 000 комплексных отсчётов RX, 0,1 с. +Все три команды hackrf_transfer работали только с `-r`, на одной частоте +и с одинаковыми RX-параметрами. Журнал команд не содержит `-t`. + +| Метрика сохранённого RX | Значение | +|---|---:| +| Размер CS8 | 1 600 000 байт | +| Комплексных отсчётов | 800 000 | +| Полная средняя мощность | 4,85388125 код² | +| Мощность после удаления среднего | 0,6658039582 код² | +| RMS полного IQ | 2,203152571 код | +| Среднее I / Q | 0,92535625 / 1,82532 код | +| Максимум абсолютного I / Q | 4 / 6 код | +| Максимальная комплексная амплитуда | 6,08276253 код | +| Отсчётов с rail-кодами −128/127 | 0 | +| RX overruns | 0 | + +Цифровых признаков насыщения в этом RX-only фоне нет. Это не доказывает +отсутствие перегрузки при включённом TX: его сигнал пока отсутствовал. +Из этих отсчётов также нельзя установить абсолютную RF-мощность или +доказать отсутствие аналоговой компрессии. При будущем разрешённом запуске +сохраняются подготовленные проверки клиппинга без автоподбора gain. + +SHA-256 RX: `c4257f26e4cc8562eb32228f9a50fdeb055879c928af0744cdf4a81cf7cd085b`. +SHA-256 TX: `5b34bbe1a8e6d037d2d6d367a74e9eb84e8940db7da61600ffaa7f7497d4f600`. +После проверки CLKOUT обеих плат выключены успешно, процессы CLEAR, +ошибок cleanup нет. Больше аппаратных действий не выполнялось. + +## Доказательства и STOP + +- [План и описание геометрии](../data/processed/lab056/rx_preflight_plan.json). +- [Журнал фактических команд с временем и выводом](../data/processed/lab056/rx_preflight_commands.json). +- [Результат RX-only preflight](../data/processed/lab056/rx_preflight_result.json). +- Исходный RX и исходный результат: `data/raw/lab056/preflight_rx.cs8`, + `preflight_result.json`; маркер попытки: `preflight_attempt.json`. + +Код и TX waveform не менялись. Последние программные проверки относятся +к этой же версии: 44 целевых теста, quick_gate 867/30/13 PASS и pytest +867 passed. Полные тесты повторно не запускались для записи аппаратного +результата. Git diff --check PASS. Lab054 NOT_A, 0/16 сохранён. + +Verifier проверил только сохранённые файлы: 12 команд, три RX-start, +ни одной TX-команды; регистры, CLKIN, cleanup и параметры подтверждены +по исходному выводу. Целочисленный пересчёт мощности/клиппинга и SHA +полностью согласован с JSON. Воспроизведённых расхождений нет, PASS. +Дополнительных аппаратных команд verifier не выполнял. + +HEAD `5add95ecb8865f59075bbbced08d97b183fb3b48`. Lab056 не коммитилась, +push не выполнялся. Технические условия preflight выполнены; отдельного +разрешения на единственный ABAB TX ещё нет. **STOP.** diff --git a/experiments/lab054_hardware_control.py b/experiments/lab054_hardware_control.py new file mode 100644 index 0000000..2bf88c0 --- /dev/null +++ b/experiments/lab054_hardware_control.py @@ -0,0 +1,359 @@ +"""Lab054: подготовка короткого BPSK-контроля; RF только отдельной командой.""" + +from __future__ import annotations + +import argparse +import hashlib +import json +from pathlib import Path +import subprocess +import sys +import time + +if __package__ in (None, ""): + sys.path.insert(0, str(Path(__file__).resolve().parents[1])) + +import numpy as np + +from experiments import lab047_jpeg_object_transport as hardware +from experiments import lab049_bpsk_symbol_rate as phy +from experiments.lab053_packet_processing import bind +from experiments.lab053_streaming_receiver import StreamingReceiver +from tools.hackrf_process_check import check_processes, require_clear + +clock = hardware.lab044.lab043 +MODE = phy.PhyMode(500_000) +RF_HZ = 1_400_000_000 +PACKETS = 16 +RX_SECONDS = 3 +RX_LEAD_SECONDS = 0.5 +RX_SAMPLES = RX_SECONDS * MODE.sample_rate_hz +DIRECTORY = Path("data/raw/lab054") +OUTPUT = Path("data/processed/lab054") + + +def save(path: Path, value: dict) -> None: + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(json.dumps(value, ensure_ascii=False, indent=2), encoding="utf-8") + + +def plans(): + """Обычный бинарный объект, 16 фрагментов прежнего формата; не видеопоток.""" + random_generator = np.random.default_rng(54054) + data = random_generator.integers(0, 256, PACKETS * phy.lab046.FRAGMENT_DATA_SIZE, dtype=np.uint8) + return phy.lab046.build_object_frames(data.tobytes(), object_id=54054) + + +def parameters() -> dict: + return {"rf_hz": RF_HZ, "sample_rate_hz": MODE.sample_rate_hz, + "symbol_rate": MODE.symbol_rate, "samples_per_symbol": MODE.samples_per_symbol, + "carrier_hz": phy.lab045.CARRIER_OFFSET_HZ, + "master_tx": clock.MASTER_SERIAL, "slave_rx": clock.SLAVE_SERIAL, + "tx_vga_db": 10, "rx_lna_db": 24, "rx_vga_db": 24, + "amplifier": False, "bias_tee": False, + "threshold": hardware.FIXED_HARDWARE_CANDIDATE_THRESHOLD} + + +def transfer_command(serial: str, path: Path | str, samples: int, *, transmit=False) -> list[str]: + command = [str(clock.HACKRF_TOOLS_DIR / "hackrf_transfer.exe"), "-d", serial, + "-t" if transmit else "-r", str(path), "-f", str(RF_HZ), + "-s", str(MODE.sample_rate_hz), "-n", str(samples)] + command += ["-x", "10"] if transmit else ["-l", "24", "-g", "24"] + return command + ["-a", "0", "-p", "0", "-B"] + + +def short_receive(serial, runner): + """Штатный запуск приёмника для выбора опоры, без передающего режима.""" + result = runner(transfer_command(serial, "NUL", clock.SHORT_RX_SAMPLE_COUNT)) + if result.returncode: + raise RuntimeError(f"Короткий RX не выполнен: {result.stderr}") + + +def disable_clock_outputs(runner) -> list[str]: + """Попытаться отключить обе платы даже при timeout первой команды.""" + errors = [] + for serial in (clock.MASTER_SERIAL, clock.SLAVE_SERIAL): + try: + clock._set_clkout(serial, False, runner) + except Exception as error: + errors.append(f"{serial}: {error}") + return errors + + +clock_preflight = bind(clock.common_clock_preflight, _short_rx=short_receive, + _disable_clock_outputs=disable_clock_outputs) + + +def preflight_only(directory: Path = OUTPUT, runner=None, process_checker=None) -> dict: + """Реальный RX-only preflight; выходы тактирования выключаются в finally.""" + runner = runner or clock._default_command_runner + process_checker = process_checker or check_processes + record = {"rf_tx_count": 0, "passed": False} + guard = clock.TransmitGuard() + clock_started = False + try: + process_state = process_checker() + record["process_check"] = process_state.to_dict() + require_clear(process_state) + record["inventory"] = phy.lab045._verify_device_inventory(runner) + clock_started = True + record["clock"] = clock_preflight(runner, guard) + record["passed"] = True + except Exception as error: + record["error"] = str(error) + raise + finally: + record["cleanup_errors"] = disable_clock_outputs(runner) if clock_started else [] + record["cleanup_performed"] = clock_started + if clock_started: + try: + process_state = process_checker() + record["process_check_after_cleanup"] = process_state.to_dict() + require_clear(process_state) + except Exception as error: + record["cleanup_errors"].append(str(error)) + record["passed"] = record["passed"] and not record["cleanup_errors"] + save(directory / "common_clock_preflight.json", record) + if not record["passed"]: + raise RuntimeError("Не удалось выключить CLKOUT") + return record + + +def prepare(directory: Path = DIRECTORY) -> dict: + directory.mkdir(parents=True, exist_ok=True) + path = directory / "tx_stream.cs8" + if path.exists(): + raise FileExistsError("TX-файл уже существует; подготовка его не перезаписывает") + with path.open("xb") as stream: + for frame in plans(): + stream.write(phy.build_parameterized_tx_cs8(frame.plan, MODE)) + count = path.stat().st_size // 2 + result = {"stage": "PREPARATION_ONLY", "rf_tx_count": 0, + "head": subprocess.check_output(["git", "rev-parse", "HEAD"], text=True).strip(), + "parameters": parameters(), "packets": PACKETS, "tx_samples": count, + "tx_bytes": path.stat().st_size, "tx_seconds": count / MODE.sample_rate_hz, + "tx_sha256": hardware._sha256_file(path), "rx_seconds": RX_SECONDS, + "rx_samples": RX_SAMPLES, "rx_lead_seconds": RX_LEAD_SECONDS, + "rx_command": transfer_command(clock.SLAVE_SERIAL, directory / "rx_stream.cs8", RX_SAMPLES), + "tx_command": transfer_command(clock.MASTER_SERIAL, path, count, transmit=True)} + save(directory / "tx_metadata.json", result) + save(OUTPUT / "preparation.json", result) + return result + + +def validate_prepared(directory: Path) -> dict: + metadata = json.loads((directory / "tx_metadata.json").read_text(encoding="utf-8")) + path = directory / "tx_stream.cs8" + expected = hashlib.sha256() + count = 0 + for frame in plans(): + waveform = phy.build_parameterized_tx_cs8(frame.plan, MODE) + expected.update(waveform) + count += len(waveform) + if (metadata["parameters"] != parameters() or metadata["stage"] != "PREPARATION_ONLY" + or metadata["rf_tx_count"] != 0 or metadata["packets"] != PACKETS + or metadata["tx_samples"] * 2 != count or path.stat().st_size != count + or metadata["tx_sha256"] != expected.hexdigest() + or hardware._sha256_file(path) != expected.hexdigest()): + raise RuntimeError("TX-артефакты или параметры изменены") + return metadata + + +def decode_file(path: Path) -> tuple[dict, list]: + """RX получает только CS8-файл; TX truth отсутствует в интерфейсе.""" + observations = [] + receiver = StreamingReceiver(packet_observer=lambda row, outcome: observations.append((row.copy(), outcome))) + received = [] + clipping = 0 + try: + with path.open("rb") as stream: + while block := stream.read(2 * 65536): + values = np.frombuffer(block, np.int8) + if len(values) % 2: + raise ValueError("Неполный IQ-отсчёт") + clipping += int(np.count_nonzero((values == -128) | (values == 127))) + samples = (values[::2].astype(np.float32) + 1j * values[1::2]).astype(np.complex64) + received.extend(receiver.push_iq_block(samples)) + received.extend(receiver.finish()) + finally: + if not receiver.closed: + receiver.finish() + rows = [] + for row, outcome in observations: + frame = outcome.frame + rows.append({"accepted": outcome.accepted, "reason": outcome.reason, + "sync_pass": outcome.refinement_pass and outcome.timing_pass and outcome.carrier_pass, + "phy_header_pass": outcome.phy_header_pass, "fec_pass": outcome.fec_pass, + "crc": outcome.crc, "start": row["absolute_refined"], + "timing": frame.timing_offset_samples if frame else None, + "cfo_hz": frame.estimated_cfo_hz if frame else None, + "phase_rad": frame.estimated_phase_rad if frame else None, + "snr_db": frame.snr_db if frame else None, + "preamble_errors": frame.preamble_errors if frame else None}) + return {"independent": True, "packets": len(received), + "frames_detected": len({r["start"] for r in rows if r["sync_pass"]}), + "frames_detected_definition": "Unique refined starts with refinement/timing/carrier PASS; may include false candidates", + "strict_candidates": len(rows), "phy_header_pass": sum(r["phy_header_pass"] for r in rows), + "fec_pass": sum(r["fec_pass"] for r in rows), + "crc_pass": sum(r["crc"] == phy.lab045.CRC_PASS for r in rows), + "crc_fail": sum(r["crc"] == phy.lab045.CRC_FAIL for r in rows), + "clipping_components": clipping, "rows": rows}, observations + + +def roundtrip(directory: Path = DIRECTORY) -> dict: + validate_prepared(directory) + result, observations = decode_file(directory / "tx_stream.cs8") + result.update(compare_after_verdict(observations)) + result["passed"] = (result["packets"] == result["exact_packets"] == result["unique_exact_packets"] == PACKETS + and result["post_fec_errors"] == 0) + save(OUTPUT / "software_roundtrip.json", result) + if not result["passed"]: + raise RuntimeError("Программный roundtrip FAIL") + return result + + +def compare_after_verdict(observations) -> dict: + """Сверка разрешена только после завершения независимого приёма.""" + by_payload = {frame.plan.payload: frame.plan for frame in plans()} + comparisons = [] + matched_payloads = set() + exact_count = 0 + for _, outcome in observations: + if outcome.accepted and outcome.frame: + frame = outcome.frame + plan = by_payload.get(frame.reception.payload_bytes) + if plan is not None: + if frame.reception.packet_bytes == plan.packet: + matched_payloads.add(frame.reception.payload_bytes) + exact_count += 1 + comparisons.append(phy.lab045.diagnostic_pre_and_post_fec( + frame.reception, frame.post_preamble_soft, plan)) + return {"exact_packets": exact_count, "unique_exact_packets": len(matched_payloads), + "payload_matched_packets": len(comparisons), + "pre_fec_errors": sum(item["pre_fec_coded"]["bit_errors"] for item in comparisons) if comparisons else None, + "post_fec_errors": sum(item["post_fec_packet"]["bit_errors"] for item in comparisons) if comparisons else None, + "error_scope": "CRC accepted packets matched by payload AFTER independent verdict; unmatched packets UNKNOWN"} + + +def analyze_capture(directory: Path = DIRECTORY) -> dict: + """Офлайн-анализ сохранённой записи, без повторной передачи.""" + evidence = json.loads((directory / "capture_result.json").read_text(encoding="utf-8")) + path = directory / "rx_stream.cs8" + if evidence.get("rx_sha256") != hardware._sha256_file(path): + raise RuntimeError("Нет подтверждённого SHA записи") + result, observations = decode_file(path) + save(OUTPUT / "independent_result.json", result) + result.update(compare_after_verdict(observations)) + result.update(frames_tx=PACKETS, rx_overruns="UNKNOWN_UNLESS_EXPLICIT_IN_LOG", + tx_underruns="UNKNOWN_UNLESS_EXPLICIT_IN_LOG") + result["result"] = "A" if (result["unique_exact_packets"] >= 15 and evidence["passed"] + and result["post_fec_errors"] == 0 + and result["clipping_components"] == 0) else "NOT_A" + result["scope"] = "One short control only; no long-term stability or video RF claim" + save(OUTPUT / "hardware_result.json", result) + return result + + +def capture_once(directory: Path = DIRECTORY, *, authorization=False, runner=None, + process_starter=None, process_checker=None, sleep_function=time.sleep) -> dict: + """Один конечный TX; эксклюзивный маркер запрещает повтор после любой ошибки.""" + if authorization is not True: + raise PermissionError("Нужно отдельное разрешение пользователя на Lab054 RF") + metadata = validate_prepared(directory) + runner = runner or clock._default_command_runner + process_starter = process_starter or clock._default_process_starter + process_checker = process_checker or check_processes + with (directory / "hardware_attempt.json").open("x", encoding="utf-8") as stream: + json.dump({"authorized_once": True, "automatic_retry": False}, stream) + guard = clock.TransmitGuard() + process = None + clock_started = False + result = {"passed": False, "rf_tx_count": 0} + try: + process_state = process_checker() + result["process_check"] = process_state.to_dict() + require_clear(process_state) + result["inventory"] = phy.lab045._verify_device_inventory(runner) + clock_started = True + result["clock"] = clock_preflight(runner, guard) + receive_path = directory / "rx_stream.cs8" + process = process_starter(transfer_command(clock.SLAVE_SERIAL, receive_path, RX_SAMPLES), + directory / "rx_stdout.txt", directory / "rx_stderr.txt") + sleep_function(RX_LEAD_SECONDS) + if process.poll() is not None: + raise RuntimeError("RX завершился до TX") + guard.register_transmit() + result["rf_tx_count"] = guard.transmit_calls + transmitted = runner(transfer_command(clock.MASTER_SERIAL, directory / "tx_stream.cs8", + metadata["tx_samples"], transmit=True)) + (directory / "tx_stdout.txt").write_text(transmitted.stdout or "", encoding="utf-8") + (directory / "tx_stderr.txt").write_text(transmitted.stderr or "", encoding="utf-8") + if transmitted.returncode or process.wait(RX_SECONDS + 10): + raise RuntimeError("Ошибка единственного TX/RX; повтор запрещён") + process.close_logs() + if receive_path.stat().st_size != RX_SAMPLES * 2: + raise RuntimeError("Неверный размер RX") + for role in ("rx", "tx"): + log = "".join((directory / f"{role}_{kind}.txt").read_text(encoding="utf-8") for kind in ("stdout", "stderr")) + if not clock._transfer_log_is_clean(log): + raise RuntimeError(f"{role}: overrun/underrun; STOP") + result.update(passed=True, rx_sha256=hardware._sha256_file(receive_path)) + except Exception as error: + result["error"] = str(error) + raise + finally: + result["cleanup_errors"] = [] + if process is not None: + try: + process.terminate() + except Exception as error: + result["cleanup_errors"].append(str(error)) + if clock_started: + result["cleanup_errors"].extend(disable_clock_outputs(runner)) + try: + process_state = process_checker() + result["process_check_after_cleanup"] = process_state.to_dict() + require_clear(process_state) + result["lingering_processes"] = [] + except Exception as error: + result["cleanup_errors"].append(str(error)) + result["lingering_processes"] = None + result["passed"] = result["passed"] and not result["cleanup_errors"] and not result["lingering_processes"] + save(directory / "capture_result.json", result) + if not result["passed"]: + raise RuntimeError("Очистка аппаратного сеанса не прошла; STOP") + return result + + +def run_functional_tests() -> None: + assert MODE.samples_per_symbol == 16 + assert len(plans()) == PACKETS + assert "-t" not in transfer_command(clock.MASTER_SERIAL, "NUL", 65536) + try: + capture_once(authorization=False) + except PermissionError: + pass + else: + raise AssertionError("RF без разрешения") + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--stage", choices=("prepare", "roundtrip", "preflight", "capture", "analyze"), required=True) + parser.add_argument("--authorize-one-rf", action="store_true") + args = parser.parse_args() + if args.stage == "prepare": + result = prepare() + elif args.stage == "roundtrip": + result = roundtrip() + elif args.stage == "preflight": + result = preflight_only() + elif args.stage == "analyze": + result = analyze_capture() + else: + result = capture_once(authorization=args.authorize_one_rf) + print(json.dumps(result, ensure_ascii=False, indent=2)) + + +if __name__ == "__main__": + main() diff --git a/experiments/lab056_abab_energy.py b/experiments/lab056_abab_energy.py new file mode 100644 index 0000000..9f959ca --- /dev/null +++ b/experiments/lab056_abab_energy.py @@ -0,0 +1,312 @@ +"""Lab056: программная подготовка ABAB и диагностика сохранённого RX.""" + +from __future__ import annotations + +import argparse +import json +from pathlib import Path +import sys + +if __package__ in (None, ""): + sys.path.insert(0, str(Path(__file__).resolve().parents[1])) + +import numpy as np +from scipy import signal + +from experiments import lab043_pluto_to_rtlsdr as shaping +from experiments import lab055_energy_audit as energy + +SAMPLE_RATE = 8_000_000 +CARRIER = 50_000 +GAP_SAMPLES = 800_000 +RX_SAMPLES = 24_000_000 +RX_LEAD_SECONDS = .5 +RAW_DIRECTORY = energy.PROJECT_ROOT / "data/raw/lab056" +OUTPUT = energy.PROJECT_ROOT / "data/processed/lab056" + + +def save_new(path: Path, value: dict) -> None: + text = json.dumps(value, ensure_ascii=False, indent=2, allow_nan=False) + "\n" + path.parent.mkdir(parents=True, exist_ok=True) + with path.open("x", encoding="utf-8") as stream: + stream.write(text) + + +def build_burst(symbol_rate: int) -> np.ndarray: + """Прежние PRBS7/BPSK/RRC, 204,8 мс символов, RMS всего burst=44.""" + if symbol_rate not in (20000, 500000): + raise ValueError("Разрешены только два исследуемых режима") + symbols = 2. * shaping.pilot_prbs7(4096 * (symbol_rate // 20000)) - 1. + samples_per_symbol = SAMPLE_RATE // symbol_rate + waveform = shaping.shape_frame_like_lab042(symbols, samples_per_symbol) + waveform *= np.exp(2j * np.pi * CARRIER * np.arange(len(waveform)) / SAMPLE_RATE) + waveform *= 44 / np.sqrt(np.mean(abs(waveform)**2)) + values = np.empty(2 * len(waveform), dtype=np.int8) + values[::2] = np.clip(np.rint(waveform.real), -128, 127).astype(np.int8) + values[1::2] = np.clip(np.rint(waveform.imag), -128, 127).astype(np.int8) + return values + + +def prepare(directory: Path = RAW_DIRECTORY) -> dict: + """Создать единственный конечный TX-файл; аппаратная частота не назначена.""" + directory.mkdir(parents=True, exist_ok=True) + tx_path, metadata_path = directory / "tx_abab.cs8", directory / "tx_metadata.json" + if tx_path.exists() or metadata_path.exists(): + raise FileExistsError("Артефакты Lab056 уже существуют") + bursts = {rate: build_burst(rate) for rate in (20000, 500000)} + segments = [] + cursor = GAP_SAMPLES + with tx_path.open("xb") as stream: + stream.write(bytes(2 * GAP_SAMPLES)) + for label, rate in (("A1", 20000), ("B1", 500000), ("A2", 20000), ("B2", 500000)): + values = bursts[rate] + count = len(values) // 2 + complex_values = values[::2].astype(np.float32) + 1j * values[1::2].astype(np.float32) + whole, active = energy.Moments(), energy.Moments() + whole.add(complex_values) + trim = 21 * (SAMPLE_RATE // rate) + active.add(complex_values[trim:-trim]) + segments.append({"label": label, "symbol_rate": rate, "start": cursor, + "samples": count, "active_start": cursor + trim, "active_samples": count - 2 * trim, + "whole": whole.result(rate), "active": active.result(rate)}) + stream.write(values.tobytes()) + stream.write(bytes(2 * GAP_SAMPLES)) + cursor += count + GAP_SAMPLES + result = {"stage": "PREPARATION_ONLY", "rf_tx": 0, "rf_frequency_hz": None, + "physical_path": "OTA_REQUESTED_FREQUENCY_AND_GEOMETRY_PENDING", "sample_rate_hz": SAMPLE_RATE, + "carrier_hz": CARRIER, "tx_samples": cursor, "tx_bytes": 2 * cursor, + "tx_seconds": cursor / SAMPLE_RATE, "rx_samples": RX_SAMPLES, + "rx_seconds": RX_SAMPLES / SAMPLE_RATE, "rx_lead_seconds": RX_LEAD_SECONDS, + "gap_seconds": GAP_SAMPLES / SAMPLE_RATE, "gap_is_zero_digital_iq_not_rf_off": True, + "tx_sha256": energy.sha256(tx_path), "segments": segments, + "whole_power_difference_db": float(10 * np.log10(segments[1]["whole"]["power_code2"] / segments[0]["whole"]["power_code2"])), + "active_power_difference_db": float(10 * np.log10(segments[1]["active"]["power_code2"] / segments[0]["active"]["power_code2"]))} + if abs(result["whole_power_difference_db"]) > .01 or any(s["whole"]["clipped_samples_fraction"] for s in segments): + raise RuntimeError("Цифровая подготовка не прошла проверку мощности/клиппинга") + save_new(metadata_path, result) + return result + + +def locate_sequence(tx: energy.Cs8File, rx: energy.Cs8File) -> dict: + """Диагностическое согласование полной ABAB; TX reference разрешён. + + Грубая сетка 32 отсчёта использует всю последовательность, затем начало + каждого burst уточняется прежним методом Lab055 на обучающей плитке. + Прореживание без антиалиасинга здесь только для корреляционного поиска, + а не для измерений мощности или спектра. + """ + stride = 32 + def decimated(source): + chunks = [source.read(start, min(262144, source.size - start))[::stride] + for start in range(0, source.size, 262144)] + return np.concatenate(chunks).astype(np.complex128) + reference, received = decimated(tx), decimated(rx) + if len(received) < len(reference): + raise ValueError("RX короче TX") + reference -= reference.mean() + received -= received.mean() + cumulative = np.concatenate(([0.], np.cumsum(abs(received)**2))) + window_energy = cumulative[len(reference):] - cumulative[:-len(reference)] + reference_energy = np.sum(abs(reference)**2) + time = np.arange(len(reference)) * stride / SAMPLE_RATE + best = (-1., 0, 0.) + for frequency in np.arange(-2., 2.01, .25): + rotated = reference * np.exp(2j * np.pi * frequency * time) + correlation = signal.fftconvolve(received, np.conj(rotated[::-1]), mode="valid") + scores = abs(correlation) / np.sqrt(np.maximum(reference_energy * window_energy, 1e-30)) + index = int(np.argmax(scores)) + if scores[index] > best[0]: + best = (float(scores[index]), index * stride, float(frequency)) + # Это качество диагностического совпадения, не критерий PHY/CRC. + if best[0] < .05: + raise ValueError("ABAB не локализована достаточно уверенно; измерение UNKNOWN") + return {"start": best[1], "correlation": best[0], "coarse_cfo_hz": best[2], "stride": stride} + + +class OffsetSource: + def __init__(self, source: energy.Cs8File, offset: int): + self.source, self.offset = source, offset + + def read(self, start: int, count: int) -> np.ndarray: + return self.source.read(self.offset + start, count) + + +def window_power(values: np.ndarray, symbol_rate: int) -> dict: + moments = energy.Moments() + moments.add(values) + result = moments.result(symbol_rate) + centered = values - values.mean() + frequencies, density = energy.spectrum(centered) + for width in (27000, 675000): + result[f"band_{width}_power"] = energy.band_power(frequencies, density, CARRIER - width / 2, CARRIER + width / 2) + size = 32000 # Неперекрывающиеся блоки по 4 мс для оценки разброса мощности. + powers = [float(np.mean(abs(centered[start:start + size])**2)) for start in range(0, len(centered) - size + 1, size)] + result["power_standard_error"] = float(np.std(powers, ddof=1) / np.sqrt(len(powers))) if len(powers) > 1 else None + return result + + +def difference_db(new: float | None, old: float | None) -> float | None: + if new is None or old is None or new <= 0 or old <= 0: + return None + return float(10 * np.log10(new / old)) + + +def complex_gain(reference: np.ndarray, received: np.ndarray, cfo_hz: float) -> dict: + """Вывести комплексный h прежней модели; те же чётные обучающие плитки.""" + boundaries = np.linspace(0, len(reference), 9, dtype=int) + train = np.zeros(len(reference), dtype=bool) + for tile in range(0, 8, 2): + train[boundaries[tile]:boundaries[tile + 1]] = True + rotated = reference * np.exp(2j * np.pi * cfo_hz * np.arange(len(reference)) / SAMPLE_RATE) + x, y = rotated[train], received[train].astype(np.complex128) + x, y = x - x.mean(), y - y.mean() + gain = np.vdot(x, y) / max(float(np.sum(abs(x)**2)), 1e-30) + return {"real": float(gain.real), "imag": float(gain.imag), + "phase_rad_at_active_start": float(np.angle(gain))} + + +def comparison_summary(rows: list[dict]) -> dict: + """Сравнить повторы отдельно; X/Z используют средние линейные мощности.""" + by_label = {row["label"]: row for row in rows} + repeatability = [] + for mode in ("A", "B"): + first, second = by_label[mode + "1"], by_label[mode + "2"] + repeatability.append({"comparison": mode + "2/" + mode + "1", + "raw_rx_power_difference_db": difference_db(second["raw_rx"]["power_code2"], first["raw_rx"]["power_code2"]), + "background_difference_db": difference_db(second["background_power"], first["background_power"]), + "received_power_difference_db": difference_db(second["background_subtracted_signal_power"], first["background_subtracted_signal_power"]), + "channel_gain_difference_db": difference_db(second["channel_gain_power"], first["channel_gain_power"]), + "matched_component_difference_db": difference_db(second["measurement"]["heldout_signal_power"], first["measurement"]["heldout_signal_power"])}) + def mean(mode, key): + values = [by_label[mode + str(number)][key] for number in (1, 2)] + return None if any(value is None or value <= 0 for value in values) else float(np.mean(values)) + a_power, b_power = mean("A", "background_subtracted_signal_power"), mean("B", "background_subtracted_signal_power") + return {"repeatability": repeatability, + "averaging": "RATIO_OF_MEAN_LINEAR_POWERS_B1_B2_OVER_A1_A2", + "received_power_difference_db": difference_db(b_power, a_power), + "channel_gain_difference_db": difference_db(mean("B", "channel_gain_power"), mean("A", "channel_gain_power")), + "energy_per_symbol_difference_db": difference_db(None if b_power is None else b_power / 500000, + None if a_power is None else a_power / 20000), + "energy_basis": "BACKGROUND_SUBTRACTED_RECEIVED_POWER_DIVIDED_BY_SYMBOL_RATE"} + + +def analyze(directory: Path, rx_path: Path) -> dict: + metadata = energy.read_json(directory / "tx_metadata.json") + tx_path = directory / "tx_abab.cs8" + if energy.sha256(tx_path) != metadata["tx_sha256"]: + raise ValueError("TX SHA не совпал") + tx, rx = energy.Cs8File(tx_path), energy.Cs8File(rx_path) + alignment = locate_sequence(tx, rx) + rows = [] + for segment in metadata["segments"]: + rate, count = segment["symbol_rate"], segment["samples"] + start = alignment["start"] + segment["start"] + measurement = energy.analyze_rx(OffsetSource(tx, segment["start"]), rx, [start], count, + SAMPLE_RATE // rate)["frames"][0] + start = measurement["start"] + trim = 21 * (SAMPLE_RATE // rate) + received_active = rx.read(start + trim, count - 2 * trim) + raw = window_power(received_active, rate) + gain = complex_gain(tx.read(segment["start"] + trim, count - 2 * trim), received_active, measurement["cfo_hz"]) + if not np.isclose(gain["real"]**2 + gain["imag"]**2, measurement["gain_abs"]**2, rtol=1e-10, atol=1e-15): + raise ValueError("Вывод комплексного h расходится с прежней моделью Lab055") + windows = [window_power(rx.read(begin, 480000), rate) for begin in + (start - 640000, start + count + 160000)] + background = float(np.mean([w["ac_power_code2"] for w in windows])) + excess = raw["ac_power_code2"] - background + uncertainty = float(np.sqrt(raw["power_standard_error"]**2 + + sum(w["power_standard_error"]**2 for w in windows) / 4 + + ((windows[0]["ac_power_code2"] - windows[1]["ac_power_code2"]) / 2)**2)) + stable = excess > 3 * uncertainty + rows.append({"label": segment["label"], "symbol_rate": rate, "raw_rx": raw, + "local_zero_iq_background_windows": windows, "background_power": background, + "background_subtracted_raw": excess, "background_subtracted_uncertainty": uncertainty, + "background_subtracted_stable": stable, "background_subtracted_signal_power": excess if stable else None, + "channel_gain_complex": gain, "channel_gain_power": measurement["gain_abs"]**2, "measurement": measurement}) + by_label = {r["label"]: r for r in rows} + pairs = [] + for number in (1, 2): + a, b = by_label[f"A{number}"], by_label[f"B{number}"] + pairs.append({"pair": number, + "received_power_difference_db": difference_db(b["background_subtracted_signal_power"], a["background_subtracted_signal_power"]), + "channel_gain_difference_db": difference_db(b["channel_gain_power"], a["channel_gain_power"]), + "matched_component_difference_db": difference_db(b["measurement"]["heldout_signal_power"], a["measurement"]["heldout_signal_power"]), + "matched_component_symbol_energy_difference_db": difference_db(b["measurement"]["heldout_signal_power"] / b["symbol_rate"], a["measurement"]["heldout_signal_power"] / a["symbol_rate"])}) + # До начала и после конца всего цифрового файла: отдельные внешние окна. + outside = [] + for begin in (alignment["start"] - 800000, alignment["start"] + tx.size + 400000): + if 0 <= begin and begin + 400000 <= rx.size: + outside.append({"start": begin, **window_power(rx.read(begin, 400000), 20000)}) + return {"scope": "TX_REFERENCE_DIAGNOSTICS_NOT_INDEPENDENT_PACKET_RX", "rf_tx": 0, + "tx_sha256": metadata["tx_sha256"], "rx_sha256": energy.sha256(rx_path), + "alignment": alignment, "segments": rows, "pairs": pairs, "comparison_summary": comparison_summary(rows), + "outside_waveform_background": outside, + "background_note": "Внутренние gaps: нулевой цифровой IQ при работающем TX; это не RF OFF. Внешние окна также требуют сверки времён запуска/остановки по журналам.", + "power_units": "RX code squared, not calibrated watts/dBm", + "residual_note": "Шум и неописанные моделью искажения; RX не нормируется для выравнивания A/B"} + + +def software_capture(directory: Path, b_gain: float, name: str) -> dict: + """Синтетический CS8 с известным усилением, DC и CFO; не аппаратная запись.""" + metadata = energy.read_json(directory / "tx_metadata.json") + tx = energy.Cs8File(directory / "tx_abab.cs8") + path = directory / f"synthetic_{name}.cs8" + random_generator = np.random.default_rng(56056) + lead = 4_160_013 + with path.open("xb") as stream: + for low in range(0, RX_SAMPLES, 262144): + count = min(262144, RX_SAMPLES - low) + values = (1 + 2j + .6 * (random_generator.normal(size=count) + 1j * random_generator.normal(size=count))) + first, last = max(low, lead), min(low + count, lead + tx.size) + if first < last: + source = tx.read(first - lead, last - first) + gains = np.full(len(source), .03) + indexes = np.arange(first - lead, last - lead) + for segment in metadata["segments"]: + if segment["label"].startswith("B"): + gains[(indexes >= segment["start"]) & (indexes < segment["start"] + segment["samples"])] = b_gain + values[first - low:last - low] += source * gains * np.exp(1j * (.7 + 2 * np.pi * .2 * np.arange(first, last) / SAMPLE_RATE)) + packed = np.empty(2 * count, dtype=np.int8) + packed[::2] = np.clip(np.rint(values.real), -128, 127) + packed[1::2] = np.clip(np.rint(values.imag), -128, 127) + stream.write(packed.tobytes()) + result = analyze(directory, path) + expected = 20 * np.log10(b_gain / .03) + errors = [abs(p["channel_gain_difference_db"] - expected) for p in result["pairs"]] + result.update(synthetic=True, expected_gain_difference_db=float(expected), + known_sequence_start=lead, passed=bool(max(errors) < .3)) + if not result["passed"]: + raise RuntimeError(f"Синтетическая проверка не прошла: {errors}") + return result + + +def run_functional_tests() -> None: + assert difference_db(.25, 1) == 10 * np.log10(.25) + assert difference_db(None, 1) is None + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("stage", choices=("prepare", "software", "analyze")) + parser.add_argument("--rx", type=Path) + parser.add_argument("--output", type=Path) + args = parser.parse_args() + if args.stage == "prepare": + result = prepare() + save_new(OUTPUT / "preparation.json", result) + elif args.stage == "software": + for name, gain in (("equal", .03), ("minus6db", .015)): + result = software_capture(RAW_DIRECTORY, gain, name) + save_new(OUTPUT / f"software_{name}.json", result) + print(name, result["pairs"], flush=True) + return + else: + if args.rx is None or args.output is None: + parser.error("Для сохранённого RX нужны --rx и новый --output") + result = analyze(RAW_DIRECTORY, args.rx) + save_new(args.output, result) + print(json.dumps(result, ensure_ascii=False, indent=2)) + + +if __name__ == "__main__": + main() diff --git a/experiments/lab056_capture_runner.py b/experiments/lab056_capture_runner.py new file mode 100644 index 0000000..56eca46 --- /dev/null +++ b/experiments/lab056_capture_runner.py @@ -0,0 +1,263 @@ +"""Lab056: конечный RX-first runner; этот модуль не имеет аппаратного CLI.""" + +from __future__ import annotations + +from dataclasses import asdict, dataclass +import json +from pathlib import Path +import re +import time + +from experiments import lab054_hardware_control as previous +from experiments import lab056_abab_energy as waveform + + +@dataclass(frozen=True) +class OperatingPoint: + """Частота пользователя и описание неподвижного эфирного тракта.""" + + frequency_hz: int | None = None + physical_path: str = "MASTER TX -> TX antenna -> free space -> RX antenna -> SLAVE RX" + path_confirmed: bool = False + tx_antenna: str = "UNKNOWN" + rx_antenna: str = "UNKNOWN" + distance_m: float | None = None + orientation: str = "UNKNOWN" + visibility: str = "UNKNOWN" + + def validate(self) -> None: + # Допустимую лабораторную частоту определяет пользователь, не этот модуль. + if type(self.frequency_hz) is not int or self.frequency_hz <= 0: + raise PermissionError("Нужно конкретное целое RF_FREQ в Гц от пользователя") + + +def command(point: OperatingPoint, path: Path | str, samples: int, *, transmit: bool = False) -> list[str]: + point.validate() + if not isinstance(samples, int) or samples <= 0: + raise ValueError("Нужен положительный конечный счётчик отсчётов") + clock = previous.clock + result = [str(clock.HACKRF_TOOLS_DIR / "hackrf_transfer.exe"), "-d", + clock.MASTER_SERIAL if transmit else clock.SLAVE_SERIAL, "-t" if transmit else "-r", + str(path), "-f", str(point.frequency_hz), "-s", str(waveform.SAMPLE_RATE), "-n", str(samples)] + return result + (["-x", "10"] if transmit else ["-l", "24", "-g", "24"]) + ["-a", "0", "-p", "0", "-B"] + + +def common_clock(point: OperatingPoint, runner, guard, *, sleep_function=time.sleep) -> dict: + """Прежняя логика регистров/CLKIN; короткий RX использует новую согласованную RF.""" + point.validate() + def short_receive(serial, command_runner): + parameters = command(point, "NUL", previous.clock.SHORT_RX_SAMPLE_COUNT) + parameters[parameters.index("-d") + 1] = serial + result = command_runner(parameters) + if result.returncode: + raise RuntimeError("Короткий RX-start не выполнен") + preflight = previous.bind(previous.clock.common_clock_preflight, _short_rx=short_receive, + _disable_clock_outputs=previous.disable_clock_outputs) + return preflight(runner, guard, sleep_function=sleep_function) + + +def validated_metadata(directory: Path) -> dict: + metadata = waveform.energy.read_json(directory / "tx_metadata.json") + path = directory / "tx_abab.cs8" + if (metadata["stage"] != "PREPARATION_ONLY" or metadata["rf_tx"] != 0 or + metadata["sample_rate_hz"] != waveform.SAMPLE_RATE or metadata["carrier_hz"] != waveform.CARRIER or + metadata["tx_samples"] * 2 != path.stat().st_size or + waveform.energy.sha256(path) != metadata["tx_sha256"] or + metadata["rx_samples"] != waveform.RX_SAMPLES or + [(s["label"], s["symbol_rate"]) for s in metadata["segments"]] != + [("A1", 20000), ("B1", 500000), ("A2", 20000), ("B2", 500000)] or + abs(metadata["whole_power_difference_db"]) > .01): + raise ValueError("Подготовленный TX/параметры изменились") + return metadata + + +def clean_counter_log(log: str, expected: str) -> bool: + """Все упоминания потерь должны быть разобраны и иметь явный нулевой счётчик.""" + pattern = re.compile(r"(? None: + if (not result.get("passed") or result.get("master_reg29") != 0x26 or + result.get("slave_reg29") != 0x26 or result.get("slave_clkin_status") != "DETECTED"): + raise RuntimeError("Common clock FAIL") + + +def receive_level(path: Path, *, tail_samples: int | None = None) -> dict: + """Уровень CS8 без изменения gain; rail-коды являются признаком клиппинга.""" + source = waveform.energy.Cs8File(path) + if source.size < 65536: + raise RuntimeError("Недостаточно сохранённых RX-отсчётов для проверки уровня") + start = max(0, source.size - tail_samples) if tail_samples else 0 + moments = waveform.energy.Moments() + for begin in range(start, source.size, 262144): + moments.add(source.read(begin, min(262144, source.size - begin))) + result = moments.result(20000) + result["saturation_detected"] = result["clipped_samples_fraction"] > 0 + result["analog_compression"] = "UNKNOWN_WITHOUT_CALIBRATION" + return result + + +def preflight_only(directory: Path, point: OperatingPoint, *, runner=None, + process_checker=None, clock_checker=None, sleep_function=time.sleep) -> dict: + """Только RX: опора и 0,1 с фона; сохранить результат и STOP до разрешения TX.""" + point.validate() + metadata = validated_metadata(directory) + waveform.save_new(directory / "preflight_attempt.json", {"point": asdict(point), "rf_tx_count": 0}) + actual_runner = runner or previous.clock._default_command_runner + process_checker = process_checker or previous.check_processes + clock_checker = clock_checker or common_clock + def receive_only_runner(parameters): + if "-t" in parameters: + raise PermissionError("TX запрещён внутри preflight_only") + return actual_runner(parameters) + record = {"passed": False, "rf_tx_count": 0, "point": asdict(point), + "tx_sha256": metadata["tx_sha256"], "stop_before_tx": True} + clock_started = False + try: + before = process_checker() + record["process_before"] = before.to_dict() + previous.require_clear(before) + record["inventory"] = previous.phy.lab045._verify_device_inventory(receive_only_runner) + clock_started = True + record["clock"] = clock_checker(point, receive_only_runner, previous.clock.TransmitGuard(), + sleep_function=sleep_function) + require_clock_pass(record["clock"]) + path = directory / "preflight_rx.cs8" + if path.exists(): + raise FileExistsError("RX preflight уже существует") + captured = receive_only_runner(command(point, path, 800000)) + record["rx_process"] = {"returncode": captured.returncode, + "stdout": captured.stdout, "stderr": captured.stderr} + if captured.returncode or not clean_counter_log(captured.stdout + captured.stderr, "overrun"): + raise RuntimeError("RX preflight: ошибка процесса или счётчиков") + if path.stat().st_size != 1600000: + raise RuntimeError("Неверный размер RX preflight") + record["rx_level"] = receive_level(path) + record["rx_sha256"] = waveform.energy.sha256(path) + if record["rx_level"]["saturation_detected"]: + raise RuntimeError("RX saturation до TX; STOP без изменения gains") + record["passed"] = True + except Exception as error: + record["error"] = str(error) + raise + finally: + errors = previous.disable_clock_outputs(receive_only_runner) if clock_started else [] + try: + after = process_checker() + record["process_after"] = after.to_dict() + previous.require_clear(after) + except Exception as error: + errors.append(str(error)) + record["cleanup_errors"] = errors + record["passed"] = record["passed"] and not errors + waveform.save_new(directory / "preflight_result.json", record) + if not record["passed"]: + raise RuntimeError("Preflight cleanup FAIL") + return record + + +def require_preflight(directory: Path, point: OperatingPoint, metadata: dict) -> None: + record = waveform.energy.read_json(directory / "preflight_result.json") + if (record.get("passed") is not True or record.get("rf_tx_count") != 0 or + record.get("point") != asdict(point) or record.get("tx_sha256") != metadata["tx_sha256"]): + raise PermissionError("Нужен успешный RX-only preflight именно этой конфигурации") + require_clock_pass(record.get("clock", {})) + if record.get("rx_level", {}).get("saturation_detected") is not False: + raise PermissionError("Нет подтверждённой проверки уровня RX до TX") + + +def capture_once(directory: Path, point: OperatingPoint, *, authorization: bool = False, + runner=None, process_starter=None, process_checker=None, + clock_checker=None, sleep_function=time.sleep) -> dict: + """Один RX и один TX; ошибка расходует попытку, автоматического повтора нет.""" + if authorization is not True: + raise PermissionError("Нужно отдельное разрешение на конкретный RF-сеанс Lab056") + point.validate() + metadata = validated_metadata(directory) + require_preflight(directory, point, metadata) + receive_path = directory / "rx_stream.cs8" + if receive_path.exists() or (directory / "capture_result.json").exists(): + raise FileExistsError("Аппаратные результаты уже существуют") + runner = runner or previous.clock._default_command_runner + process_starter = process_starter or previous.clock._default_process_starter + process_checker = process_checker or previous.check_processes + clock_checker = clock_checker or common_clock + waveform.save_new(directory / "hardware_attempt.json", {"authorized_once": True, + "point": asdict(point), "tx_sha256": metadata["tx_sha256"], "automatic_retry": False}) + result = {"passed": False, "rf_tx_count": 0, "point": asdict(point)} + guard = previous.clock.TransmitGuard() + process, clock_started = None, False + try: + before = process_checker() + result["process_before"] = before.to_dict() + previous.require_clear(before) + result["inventory"] = previous.phy.lab045._verify_device_inventory(runner) + clock_started = True + result["clock"] = clock_checker(point, runner, guard, sleep_function=sleep_function) + require_clock_pass(result["clock"]) + process = process_starter(command(point, receive_path, waveform.RX_SAMPLES), + directory / "rx_stdout.txt", directory / "rx_stderr.txt") + sleep_function(waveform.RX_LEAD_SECONDS) + if process.poll() is not None: + raise RuntimeError("RX завершился до TX") + result["rx_level_before_tx"] = receive_level(receive_path, tail_samples=65536) + if result["rx_level_before_tx"]["saturation_detected"]: + raise RuntimeError("RX saturation до TX; STOP без изменения gains") + guard.register_transmit() + result["rf_tx_count"] = guard.transmit_calls + transmitted = runner(command(point, directory / "tx_abab.cs8", metadata["tx_samples"], transmit=True)) + waveform.save_new(directory / "tx_process_result.json", {"returncode": transmitted.returncode, + "stdout": transmitted.stdout, "stderr": transmitted.stderr}) + if transmitted.returncode or process.wait(13): + raise RuntimeError("Единственный TX/RX завершился ошибкой") + process.close_logs() + if receive_path.stat().st_size != waveform.RX_SAMPLES * 2: + raise RuntimeError("Неверный размер RX") + rx_log = "".join((directory / f"rx_{kind}.txt").read_text(encoding="utf-8") for kind in ("stdout", "stderr")) + for role, log, counter in (("RX", rx_log, "overrun"), + ("TX", transmitted.stdout + transmitted.stderr, "underrun")): + if not clean_counter_log(log, counter): + raise RuntimeError(f"{role}: нет явного нулевого счётчика потерь") + result.update(rx_sha256=waveform.energy.sha256(receive_path), rx_level=receive_level(receive_path)) + if result["rx_level"]["saturation_detected"]: + raise RuntimeError("RX saturation в сохранённом сеансе; TX уже был, повтор запрещён") + result["passed"] = True + except Exception as error: + result["error"] = str(error) + raise + finally: + errors = [] + if process is not None: + try: + process.terminate() + except Exception as error: + errors.append(str(error)) + if clock_started: + errors.extend(previous.disable_clock_outputs(runner)) + try: + after = process_checker() + result["process_after"] = after.to_dict() + previous.require_clear(after) + except Exception as error: + errors.append(str(error)) + result["cleanup_errors"] = errors + result["passed"] = result["passed"] and not errors + waveform.save_new(directory / "capture_result.json", result) + if not result["passed"]: + raise RuntimeError("Cleanup FAIL; повтор запрещён") + return result + + +def run_functional_tests() -> None: + try: + capture_once(Path("UNUSED"), OperatingPoint()) + except PermissionError: + pass + else: + raise AssertionError("Разрешение проверяется раньше любых действий") diff --git a/tests/test_hackrf_process_check.py b/tests/test_hackrf_process_check.py new file mode 100644 index 0000000..79976b1 --- /dev/null +++ b/tests/test_hackrf_process_check.py @@ -0,0 +1,159 @@ +"""Достоверность перечисления процессов и запрет аппаратных действий при FAIL.""" + +from __future__ import annotations + +import json +import subprocess +from types import SimpleNamespace + +import pytest + +from experiments import lab054_hardware_control as lab +from tools import hackrf_process_check as check + + +def snapshot(names=("python.exe",), errors=()): + return check.classify_snapshot("fixture", [check.ProcessIdentity(index + 1, name) + for index, name in enumerate(names)], errors) + + +def completed(stdout="", stderr="", code=0): + return lambda command: subprocess.CompletedProcess(command, code, stdout, stderr) + + +def test_clear_full_snapshot(): + result = check.check_processes([lambda: snapshot()]) + assert result.state is check.ProcessState.CLEAR + check.require_clear(result) + + +@pytest.mark.parametrize("name", ["hackrf_transfer.exe", "hackrf_clock.exe", "HACKRF_DEBUG.EXE", + "hackrf_info.exe", "sdrangel.exe", "SDRSharp", "gqrx"]) +def test_busy_known_sdr_clients(name): + result = check.check_processes([lambda: snapshot((name,), errors=("partial snapshot",)), + lambda: pytest.fail("BUSY запрещает fallback")]) + assert result.state is check.ProcessState.BUSY + with pytest.raises(RuntimeError): + check.require_clear(result) + + +@pytest.mark.parametrize("names,errors", [((), ()), (("python",), ("Access denied",)), (("",), ())]) +def test_unknown_never_becomes_clear(names, errors): + result = check.check_processes([lambda: snapshot(names, errors)]) + assert result.state is check.ProcessState.UNKNOWN + with pytest.raises(RuntimeError): + check.require_clear(result) + + +def test_tasklist_access_denied_is_unknown(): + result = check.scan_tasklist(completed(stderr="ERROR: Access denied", code=1)) + assert result.state is check.ProcessState.UNKNOWN + assert "Access denied" in str(result.errors) + + +def test_fallback_to_powershell_after_psutil_unavailable(monkeypatch): + powershell = check.scan_powershell + monkeypatch.setattr(check, "scan_psutil", lambda: snapshot((), ("ImportError: psutil",))) + monkeypatch.setattr(check, "scan_powershell", lambda: powershell( + completed('[{"Id":12,"ProcessName":"python"}]'))) + monkeypatch.setattr(check, "scan_tasklist", lambda: pytest.fail("Полный CLEAR уже получен")) + result = check.check_processes() + assert result.state is check.ProcessState.CLEAR + assert [item.state for item in result.attempts] == [check.ProcessState.UNKNOWN, check.ProcessState.CLEAR] + + +def test_tasklist_is_last_fallback(monkeypatch): + tasklist = check.scan_tasklist + monkeypatch.setattr(check, "scan_psutil", lambda: snapshot((), ("unavailable",))) + monkeypatch.setattr(check, "scan_powershell", lambda: snapshot((), ("denied",))) + monkeypatch.setattr(check, "scan_tasklist", lambda: tasklist( + completed('"python.exe","123","Console","1","123 K"\n'))) + result = check.check_processes() + assert result.state is check.ProcessState.CLEAR + assert len(result.attempts) == 3 + + +@pytest.mark.parametrize("output", ["", "[]", "null", "not json", '[{"Id":4,"ProcessName":null}]']) +def test_powershell_malformed_not_clear(output): + assert check.scan_powershell(completed(output)).state is check.ProcessState.UNKNOWN + + +@pytest.mark.parametrize("output", ["", "INFO: No tasks are running", '"python.exe","bad pid","a","b","c"']) +def test_tasklist_malformed_not_clear(output): + assert check.scan_tasklist(completed(output)).state is check.ProcessState.UNKNOWN + + +def test_provider_exception_and_empty_provider_list_unknown(): + def failed(): + raise PermissionError("denied") + assert check.check_processes([failed]).state is check.ProcessState.UNKNOWN + assert check.check_processes([]).state is check.ProcessState.UNKNOWN + + +@pytest.mark.parametrize("mechanism", ["powershell", "tasklist"]) +@pytest.mark.parametrize("malformed_first", [False, True]) +def test_busy_survives_malformed_neighbor(mechanism, malformed_first): + if mechanism == "powershell": + rows = [{"Id":42,"ProcessName":"hackrf_transfer"}, {}] + if malformed_first: + rows.reverse() + scan = check.scan_powershell(completed(json.dumps(rows))) + else: + rows = ['"hackrf_transfer.exe","42","Console","1","100 K"', "BROKEN"] + if malformed_first: + rows.reverse() + scan = check.scan_tasklist(completed("\n".join(rows))) + assert scan.errors + result = check.check_processes([lambda: scan, lambda: pytest.fail("Найденный BUSY нельзя потерять")]) + assert result.state is check.ProcessState.BUSY + + +@pytest.mark.parametrize("disappeared", [False, True]) +def test_psutil_access_denied_or_exited_process(monkeypatch, disappeared): + class NoSuchProcess(Exception): + pass + + def unreadable(): + raise NoSuchProcess() if disappeared else PermissionError("Access denied") + + module = SimpleNamespace(NoSuchProcess=NoSuchProcess, process_iter=lambda: iter([ + SimpleNamespace(pid=1, name=lambda: "python.exe"), + SimpleNamespace(pid=2, name=unreadable)])) + monkeypatch.setattr(check.importlib, "import_module", lambda name: module) + result = check.scan_psutil() + assert result.state is (check.ProcessState.CLEAR if disappeared else check.ProcessState.UNKNOWN) + + +@pytest.mark.parametrize("state", list(check.ProcessState)) +def test_preflight_only_clear_reaches_hardware(tmp_path, monkeypatch, state): + actions = [] + scan = snapshot(("hackrf_transfer.exe",)) if state is check.ProcessState.BUSY else snapshot() + if state is check.ProcessState.UNKNOWN: + scan = snapshot((), ("tasklist Access denied",)) + result = check.ProcessCheck(state, (scan,)) + monkeypatch.setattr(lab.phy.lab045, "_verify_device_inventory", lambda runner: actions.append("inventory") or {}) + monkeypatch.setattr(lab, "clock_preflight", lambda runner, guard: actions.append("clock") or {"passed": True}) + monkeypatch.setattr(lab, "disable_clock_outputs", lambda runner: actions.append("cleanup") or []) + if state is check.ProcessState.CLEAR: + assert lab.preflight_only(tmp_path, runner=lambda _: None, process_checker=lambda: result)["passed"] + assert actions == ["inventory", "clock", "cleanup"] + else: + with pytest.raises(RuntimeError): + lab.preflight_only(tmp_path, runner=lambda _: None, process_checker=lambda: result) + assert actions == [] + report = json.loads((tmp_path / "common_clock_preflight.json").read_text(encoding="utf-8")) + assert report["process_check"]["state"] == state.value + assert report["rf_tx_count"] == 0 + + +def test_unknown_after_cleanup_rejects_preflight(tmp_path, monkeypatch): + states = iter([check.ProcessCheck(check.ProcessState.CLEAR, (snapshot(),)), + check.ProcessCheck(check.ProcessState.UNKNOWN, (snapshot((), ("denied",)),))]) + monkeypatch.setattr(lab.phy.lab045, "_verify_device_inventory", lambda runner: {}) + monkeypatch.setattr(lab, "clock_preflight", lambda runner, guard: {"passed": True}) + monkeypatch.setattr(lab, "disable_clock_outputs", lambda runner: []) + with pytest.raises(RuntimeError): + lab.preflight_only(tmp_path, runner=lambda _: None, process_checker=lambda: next(states)) + report = json.loads((tmp_path / "common_clock_preflight.json").read_text(encoding="utf-8")) + assert not report["passed"] + assert report["process_check_after_cleanup"]["state"] == "UNKNOWN" diff --git a/tests/test_lab054_hardware_control.py b/tests/test_lab054_hardware_control.py new file mode 100644 index 0000000..0aab574 --- /dev/null +++ b/tests/test_lab054_hardware_control.py @@ -0,0 +1,140 @@ +"""Lab054: фиксированные RF-команды и отказы runner без оборудования.""" + +from __future__ import annotations + +import json +from pathlib import Path +import subprocess + +import pytest + +from experiments import lab054_hardware_control as lab +from tools.hackrf_process_check import ProcessCheck, ProcessState + + +@pytest.mark.parametrize("failure", [None, "master", "slave", "clkin", "receive"]) +def test_clock_gates_never_transmit(failure): + commands = [] + + def runner(command): + commands.append(command) + output, code = "", 0 + if "--si5351c" in command: + serial = command[command.index("-d") + 1] + bad = ((failure == "master" and serial == lab.clock.MASTER_SERIAL) + or (failure == "slave" and serial == lab.clock.SLAVE_SERIAL)) + output = "0x0e" if bad else "0x26" + elif "-i" in command: + output = "UNKNOWN" if failure == "clkin" else "CLKIN status: clock signal detected" + elif "-r" in command: + code = int(failure == "receive") + return subprocess.CompletedProcess(command, code, output, "") + + guard = lab.clock.TransmitGuard() + if failure: + with pytest.raises(RuntimeError): + lab.clock_preflight(runner, guard, sleep_function=lambda _: None) + assert not guard.tx_allowed + else: + assert lab.clock_preflight(runner, guard, sleep_function=lambda _: None)["passed"] + assert guard.tx_allowed + assert not any("-t" in command for command in commands) + for command in commands: + if Path(command[0]).name == "hackrf_transfer.exe": + assert command[command.index("-f") + 1] == "1400000000" + assert command[command.index("-l") + 1] == command[command.index("-g") + 1] == "24" + + +def test_authorization_precedes_all_side_effects(tmp_path): + with pytest.raises(PermissionError): + lab.capture_once(tmp_path, runner=lambda _: pytest.fail("hardware")) + assert list(tmp_path.iterdir()) == [] + + +@pytest.mark.parametrize("failure", [None, "clock", "early_rx", "tx", "cleanup"]) +def test_one_shot_order_and_no_retry(tmp_path, monkeypatch, failure): + events = [] + monkeypatch.setattr(lab, "validate_prepared", lambda directory: {"tx_samples": 123}) + monkeypatch.setattr(lab.phy.lab045, "_verify_device_inventory", lambda runner: {}) + + def preflight(runner, guard): + if failure == "clock": + raise RuntimeError("clock") + guard.allow() + return {"passed": True} + + monkeypatch.setattr(lab, "clock_preflight", preflight) + monkeypatch.setattr(lab, "disable_clock_outputs", lambda runner: events.append("clocks_off") or []) + + class Process: + def poll(self): + return 1 if failure == "early_rx" else None + + def wait(self, timeout): + with (tmp_path / "rx_stream.cs8").open("wb") as stream: + stream.truncate(lab.RX_SAMPLES * 2) + return 0 + + def close_logs(self): + pass + + def terminate(self): + events.append("terminate") + if failure == "cleanup": + raise RuntimeError("cleanup") + + def starter(command, stdout, stderr): + events.append("rx") + stdout.write_text("") + stderr.write_text("") + return Process() + + def runner(command): + assert "-t" in command and "-R" not in command + events.append("tx") + return subprocess.CompletedProcess(command, int(failure == "tx"), "", "") + + kwargs = dict(authorization=True, runner=runner, process_starter=starter, + process_checker=lambda: ProcessCheck(ProcessState.CLEAR, ()), + sleep_function=lambda _: events.append("lead")) + if failure: + with pytest.raises(RuntimeError): + lab.capture_once(tmp_path, **kwargs) + else: + assert lab.capture_once(tmp_path, **kwargs)["passed"] + assert events.count("tx") == (0 if failure in ("clock", "early_rx") else 1) + if "tx" in events: + assert events.index("rx") < events.index("lead") < events.index("tx") + assert "clocks_off" in events + assert json.loads((tmp_path / "capture_result.json").read_text())["passed"] == (failure is None) + before = events.copy() + with pytest.raises(FileExistsError): + lab.capture_once(tmp_path, **kwargs) + assert events == before + + +def test_clock_cleanup_continues_after_timeout(): + commands = [] + + def runner(command): + commands.append(command) + raise subprocess.TimeoutExpired(command, 1) + + errors = lab.disable_clock_outputs(runner) + assert len(commands) == len(errors) == 2 + assert [command[2] for command in commands] == [lab.clock.MASTER_SERIAL, lab.clock.SLAVE_SERIAL] + + +def test_payload_match_does_not_hide_changed_packet(): + from types import SimpleNamespace + + plan = lab.plans()[0].plan + packet = bytes([plan.packet[0] ^ 1]) + plan.packet[1:] + reception = SimpleNamespace(payload_bytes=plan.payload, packet_bytes=packet) + frame = SimpleNamespace(reception=reception, + post_preamble_soft=lab.phy.lab045.modulate_bits_to_ideal_soft( + __import__("numpy").concatenate((plan.phy_header_bits, plan.interleaved_bits)))) + result = lab.compare_after_verdict([(None, SimpleNamespace(accepted=True, frame=frame))]) + assert result["payload_matched_packets"] == 1 + assert result["exact_packets"] == result["unique_exact_packets"] == 0 + assert result["post_fec_errors"] == 1 diff --git a/tests/test_lab056_preparation.py b/tests/test_lab056_preparation.py new file mode 100644 index 0000000..f5fed09 --- /dev/null +++ b/tests/test_lab056_preparation.py @@ -0,0 +1,248 @@ +"""Lab056: цифровые условия и отказы runner без оборудования.""" + +from __future__ import annotations + +import json +from dataclasses import asdict +from pathlib import Path +import subprocess + +import numpy as np +import pytest + +from experiments import lab056_abab_energy as lab +from experiments import lab056_capture_runner as capture +from tools.hackrf_process_check import ProcessCheck, ProcessState + + +def point(): + # Только синтетическая конфигурация теста; это не разрешение на эфир. + return capture.OperatingPoint(915000000, physical_path="SIMULATED", path_confirmed=True) + + +def test_no_authorization_has_no_side_effects(tmp_path): + with pytest.raises(PermissionError): + capture.capture_once(tmp_path, point(), runner=lambda _: pytest.fail("hardware")) + assert list(tmp_path.iterdir()) == [] + + +@pytest.mark.parametrize("configuration", [capture.OperatingPoint(), + capture.OperatingPoint(0), capture.OperatingPoint(True), capture.OperatingPoint(915e6)]) +def test_missing_or_invalid_frequency_precedes_io(tmp_path, configuration): + with pytest.raises(PermissionError): + capture.capture_once(tmp_path, configuration, authorization=True) + with pytest.raises(PermissionError): + capture.preflight_only(tmp_path, configuration) + assert list(tmp_path.iterdir()) == [] + + +def test_fixed_gain_and_finite_nonrepeating_commands(): + rx = capture.command(point(), "rx.cs8", 24000000) + tx = capture.command(point(), "tx.cs8", 1000000, transmit=True) + assert rx[rx.index("-l") + 1] == rx[rx.index("-g") + 1] == "24" + assert tx[tx.index("-x") + 1] == "10" + for command in (rx, tx): + assert "-R" not in command + assert command[command.index("-a") + 1] == command[command.index("-p") + 1] == "0" + assert command[command.index("-f") + 1] == "915000000" + assert command[command.index("-s") + 1] == "8000000" + + +@pytest.mark.parametrize("failure", [None, "master", "slave", "clkin", "receive"]) +def test_common_clock_logic_uses_agreed_frequency(failure): + commands = [] + def runner(command): + commands.append(command) + output, code = "", 0 + if "--si5351c" in command: + serial = command[command.index("-d") + 1] + bad = ((failure == "master" and serial == capture.previous.clock.MASTER_SERIAL) or + (failure == "slave" and serial == capture.previous.clock.SLAVE_SERIAL)) + output = "0x0e" if bad else "0x26" + elif "-i" in command: + output = "UNKNOWN" if failure == "clkin" else "CLKIN status: clock signal detected" + elif "-r" in command: + code = int(failure == "receive") + assert command[command.index("-f") + 1] == "915000000" + return subprocess.CompletedProcess(command, code, output, "") + guard = capture.previous.clock.TransmitGuard() + if failure: + with pytest.raises(RuntimeError): + capture.common_clock(point(), runner, guard, sleep_function=lambda _: None) + assert not guard.tx_allowed + else: + assert capture.common_clock(point(), runner, guard, sleep_function=lambda _: None)["passed"] + assert not any("-t" in command for command in commands) + + +@pytest.mark.parametrize("failure", [None, "busy", "clock", "early_rx", "tx", "counters", "cleanup", "rx_role_loss", "tx_role_loss", "clipping_before", "clipping_during"]) +def test_one_shot_rx_first_and_failures(tmp_path, monkeypatch, failure): + events = [] + monkeypatch.setattr(capture, "validated_metadata", lambda _: {"tx_sha256": "TEST", "tx_samples": 200}) + monkeypatch.setattr(capture.previous.phy.lab045, "_verify_device_inventory", lambda _: {"passed": True}) + monkeypatch.setattr(lab, "RX_SAMPLES", 65536) + approved = {"passed": True, "rf_tx_count": 0, "point": asdict(point()), "tx_sha256": "TEST", + "clock": {"passed": True, "master_reg29": 38, "slave_reg29": 38, "slave_clkin_status": "DETECTED"}, + "rx_level": {"saturation_detected": False}} + lab.save_new(tmp_path / "preflight_result.json", approved) + def clock_checker(point, runner, guard, **kwargs): + events.append("clock") + if failure == "clock": + raise RuntimeError("clock") + guard.allow() + return {"passed": True, "master_reg29": 38, "slave_reg29": 38, "slave_clkin_status": "DETECTED"} + class Process: + def poll(self): + return 1 if failure == "early_rx" else None + + def wait(self, timeout): + (tmp_path / "rx_stream.cs8").write_bytes(bytes([127 if failure == "clipping_during" else 1]) * 131072) + return 0 + + def close_logs(self): + pass + + def terminate(self): + events.append("terminate") + if failure == "cleanup": + raise RuntimeError("cleanup") + def starter(command, stdout, stderr): + events.append("rx") + (tmp_path / "rx_stream.cs8").write_bytes(bytes([127 if failure == "clipping_before" else 1]) * 131072) + stdout.write_text("") + stderr.write_text("1 RX overruns\n0 overruns" if failure == "rx_role_loss" else "0 overruns") + return Process() + def runner(command): + if "-t" in command: + events.append("tx") + log = "" if failure == "counters" else ("1 TX underruns\n0 underruns" if failure == "tx_role_loss" else "0 underruns") + return subprocess.CompletedProcess(command, int(failure == "tx"), "", log) + events.append("cleanup") + return subprocess.CompletedProcess(command, 0, "", "") + kwargs = dict(authorization=True, runner=runner, process_starter=starter, + process_checker=lambda: ProcessCheck(ProcessState.BUSY if failure == "busy" else ProcessState.CLEAR, ()), + clock_checker=clock_checker, sleep_function=lambda _: events.append("lead")) + if failure: + with pytest.raises(RuntimeError): + capture.capture_once(tmp_path, point(), **kwargs) + else: + assert capture.capture_once(tmp_path, point(), **kwargs)["passed"] + assert events.count("tx") == (0 if failure in ("busy", "clock", "early_rx", "clipping_before") else 1) + if "tx" in events: + assert events.index("rx") < events.index("lead") < events.index("tx") + before = events.copy() + with pytest.raises(FileExistsError): + capture.capture_once(tmp_path, point(), **kwargs) + assert events == before + result = json.loads((tmp_path / "capture_result.json").read_text()) + assert result["passed"] == (failure is None) + assert result["rf_tx_count"] == events.count("tx") + + +@pytest.mark.parametrize("failure", [None, "clock", "clipping", "tx_attempt", "cleanup"]) +def test_rx_only_preflight_stops_before_tx(tmp_path, monkeypatch, failure): + calls = [] + monkeypatch.setattr(capture, "validated_metadata", lambda _: {"tx_sha256": "TEST"}) + monkeypatch.setattr(capture.previous.phy.lab045, "_verify_device_inventory", lambda _: {"passed": True}) + def runner(command): + calls.append(command) + assert "-t" not in command + if "-r" in command: + Path(command[command.index("-r") + 1]).write_bytes(bytes([127 if failure == "clipping" else 1]) * 1600000) + if failure == "cleanup": + raise RuntimeError("cleanup") + return subprocess.CompletedProcess(command, 0, "0 RX overruns", "") + def clock_checker(point, runner, guard, **kwargs): + if failure == "tx_attempt": + runner(["hackrf_transfer", "-t", "forbidden"]) + return {"passed": True, "master_reg29": 14 if failure == "clock" else 38, + "slave_reg29": 38, "slave_clkin_status": "DETECTED"} + kwargs = dict(runner=runner, clock_checker=clock_checker, + process_checker=lambda: ProcessCheck(ProcessState.CLEAR, ())) + if failure: + with pytest.raises((RuntimeError, PermissionError)): + capture.preflight_only(tmp_path, point(), **kwargs) + else: + assert capture.preflight_only(tmp_path, point(), **kwargs)["passed"] + result = json.loads((tmp_path / "preflight_result.json").read_text()) + assert result["rf_tx_count"] == 0 + assert result["passed"] == (failure is None) + assert not (tmp_path / "hardware_attempt.json").exists() + with pytest.raises(FileExistsError): + capture.preflight_only(tmp_path, point(), **kwargs) + + +def test_preflight_cannot_authorize_another_frequency(tmp_path): + approved = {"passed": True, "rf_tx_count": 0, "point": asdict(point()), "tx_sha256": "TEST", + "clock": {"passed": True, "master_reg29": 38, "slave_reg29": 38, "slave_clkin_status": "DETECTED"}, + "rx_level": {"saturation_detected": False}} + lab.save_new(tmp_path / "preflight_result.json", approved) + capture.require_preflight(tmp_path, point(), {"tx_sha256": "TEST"}) + with pytest.raises(PermissionError): + capture.require_preflight(tmp_path, capture.OperatingPoint(916000000), {"tx_sha256": "TEST"}) + + +def test_external_frequency_needs_no_country_or_band_fields(): + configuration = capture.OperatingPoint(916000000) + command = capture.command(configuration, "NUL", 65536) + assert command[command.index("-f") + 1] == "916000000" + + +def test_complex_gain_and_repeatability_are_not_rx_normalization(): + random_generator = np.random.default_rng(56) + reference = random_generator.normal(size=8000).astype(complex) + expected = .3 + .4j + received = 1 + 2j + expected * reference + gain = lab.complex_gain(reference, received, 0) + assert complex(gain["real"], gain["imag"]) == pytest.approx(expected) + rows = [] + for label, power in (("A1", 4), ("B1", 1), ("A2", 8), ("B2", 2)): + rows.append({"label": label, "background_power": 1, "raw_rx": {"power_code2": power + 1}, + "background_subtracted_signal_power": power, "channel_gain_power": power, + "measurement": {"heldout_signal_power": power}}) + result = lab.comparison_summary(rows) + assert result["received_power_difference_db"] == pytest.approx(-6.020599913) + assert result["energy_per_symbol_difference_db"] == pytest.approx(-20) + assert [r["channel_gain_difference_db"] for r in result["repeatability"]] == pytest.approx([3.010299957, 3.010299957]) + rows[-1]["background_subtracted_signal_power"] = None + assert lab.comparison_summary(rows)["received_power_difference_db"] is None + + +def test_nonpositive_excess_is_not_a_power_ratio(): + assert lab.difference_db(-1, 1) is None + assert lab.difference_db(None, 1) is None + assert lab.difference_db(.25, 1) == pytest.approx(-6.020599913) + + +def test_invalid_result_does_not_leave_partial_json(tmp_path): + path = tmp_path / "result.json" + with pytest.raises(ValueError): + lab.save_new(path, {"invalid": float("nan")}) + assert not path.exists() + lab.save_new(path, {"passed": True}) + with pytest.raises(FileExistsError): + lab.save_new(path, {"passed": False}) + assert json.loads(path.read_text())["passed"] is True + + +@pytest.mark.parametrize("log,expected,passed", [ + ("0 overruns", "overrun", True), ("0 RX overrun", "overrun", True), + ("0 TX underruns", "underrun", True), ("1 RX overruns\n0 overruns", "overrun", False), + ("1 TX underrun\n0 underruns", "underrun", False), + ("unknown overruns\n0 overruns", "overrun", False), + ("0 overruns\nunderrun detected", "overrun", False), + ("0.0 overruns", "overrun", False), ("-1 overruns", "overrun", False), + ("0 underruns", "overrun", False), ("", "overrun", False)]) +def test_all_loss_mentions_must_be_explicit_zero(log, expected, passed): + assert capture.clean_counter_log(log, expected) is passed + + +def test_deterministic_ab_rms_and_no_clipping(): + powers = [] + for rate in (20000, 500000): + raw = lab.build_burst(rate) + values = raw[::2].astype(float) + 1j * raw[1::2].astype(float) + assert not np.any((raw == -128) | (raw == 127)) + powers.append(float(np.mean(abs(values)**2))) + np.testing.assert_array_equal(raw, lab.build_burst(rate)) + assert abs(lab.difference_db(powers[1], powers[0])) < .01 diff --git a/tools/hackrf_process_check.py b/tools/hackrf_process_check.py new file mode 100644 index 0000000..5498e51 --- /dev/null +++ b/tools/hackrf_process_check.py @@ -0,0 +1,178 @@ +"""Проверка конфликтующих SDR-процессов без обращения к оборудованию.""" + +from __future__ import annotations + +import csv +from dataclasses import asdict, dataclass +from enum import Enum +import importlib +import io +import json +from pathlib import PureWindowsPath +import subprocess +from typing import Callable, Iterable + + +class ProcessState(str, Enum): + CLEAR = "CLEAR" + BUSY = "BUSY" + UNKNOWN = "UNKNOWN" + + +@dataclass(frozen=True) +class ProcessIdentity: + pid: int + name: str + + +@dataclass(frozen=True) +class ProcessScan: + state: ProcessState + mechanism: str + matches: tuple[ProcessIdentity, ...] = () + inspected: int = 0 + errors: tuple[str, ...] = () + + +@dataclass(frozen=True) +class ProcessCheck: + state: ProcessState + attempts: tuple[ProcessScan, ...] + + def to_dict(self) -> dict: + return asdict(self) + + +# Эти программы способны открыть SDR. Их наличие консервативно даёт BUSY, +# даже если конкретный экземпляр пока не открыл устройство. Это проверка имён, +# а не доказательство отсутствия произвольного переименованного USB-клиента. +SDR_PROCESS_NAMES = frozenset({ + "gqrx", "sdrangel", "sdrsharp", "sdrpp", "sdr++", "cubicsdr", "hdsdr", + "sdrconnect", "gnuradio-companion", "osmocom_fft", "osmocom_siggen", + "soapysdrserver", "soapyremote", "soapy_sdr_server", "urh", +}) + + +def is_conflicting(name: str) -> bool: + normalized = PureWindowsPath(name).name.casefold() + if normalized.endswith(".exe"): + normalized = normalized[:-4] + return normalized.startswith("hackrf_") or normalized in SDR_PROCESS_NAMES + + +def classify_snapshot(mechanism: str, rows: Iterable[ProcessIdentity], + errors: Iterable[str] = ()) -> ProcessScan: + """Пустое, неполное или неразобранное перечисление не означает CLEAR.""" + failures = list(errors) + matches = [] + count = 0 + try: + for row in rows: + if (not isinstance(row, ProcessIdentity) or type(row.pid) is not int or row.pid < 0 + or not isinstance(row.name, str) or not row.name.strip()): + failures.append("Некорректная запись процесса") + continue + count += 1 + if is_conflicting(row.name): + matches.append(row) + except Exception as error: + failures.append(f"{type(error).__name__}: {error}") + if count == 0: + failures.append("Не получено ни одного процесса") + state = ProcessState.BUSY if matches else (ProcessState.UNKNOWN if failures else ProcessState.CLEAR) + return ProcessScan(state, mechanism, tuple(matches), count, tuple(failures)) + + +def scan_psutil() -> ProcessScan: + """NoSuchProcess — обычное завершение; отказ доступа сохраняет UNKNOWN.""" + rows, errors = [], [] + try: + psutil = importlib.import_module("psutil") + clear_cache = getattr(psutil.process_iter, "cache_clear", None) + if clear_cache is not None: + clear_cache() + for process in psutil.process_iter(): + try: + rows.append(ProcessIdentity(process.pid, process.name())) + except psutil.NoSuchProcess: + continue + except Exception as error: + errors.append(f"pid={process.pid}: {type(error).__name__}: {error}") + except Exception as error: + errors.append(f"{type(error).__name__}: {error}") + return classify_snapshot("psutil", rows, errors) + + +def run_command(command: list[str]) -> subprocess.CompletedProcess: + return subprocess.run(command, capture_output=True, text=True, encoding="utf-8", + errors="strict", timeout=10, + creationflags=getattr(subprocess, "CREATE_NO_WINDOW", 0)) + + +def scan_powershell(runner: Callable = run_command) -> ProcessScan: + """Get-Process завершает перечисление целиком или возвращает ошибку.""" + script = ("$ErrorActionPreference='Stop'; " + "[Console]::OutputEncoding=[System.Text.UTF8Encoding]::new(); " + "try { $items=@(Get-Process -ErrorAction Stop | " + "Select-Object Id,ProcessName); " + "ConvertTo-Json -InputObject $items -Compress } " + "catch { [Console]::Error.WriteLine($_.Exception.Message); exit 1 }") + rows, errors = [], [] + try: + result = runner(["powershell.exe", "-NoLogo", "-NoProfile", "-NonInteractive", "-Command", script]) + if result.returncode != 0 or result.stderr.strip(): + raise RuntimeError(f"exit={result.returncode}: {result.stderr.strip()}") + data = json.loads(result.stdout) + if not isinstance(data, list): + raise ValueError("Ожидался полный JSON-массив процессов") + for row in data: + try: + rows.append(ProcessIdentity(row["Id"], row["ProcessName"])) + except Exception as error: + errors.append(f"{type(error).__name__}: {error}") + except Exception as error: + errors.append(f"{type(error).__name__}: {error}") + return classify_snapshot("powershell_get_process", rows, errors) + + +def scan_tasklist(runner: Callable = run_command) -> ProcessScan: + """Резервный полный CSV; текст ошибки или пустой вывод не равен CLEAR.""" + rows, errors = [], [] + try: + result = runner(["tasklist.exe", "/FO", "CSV", "/NH"]) + if result.returncode != 0 or result.stderr.strip(): + raise RuntimeError(f"exit={result.returncode}: {result.stderr.strip()}") + for row in csv.reader(io.StringIO(result.stdout), strict=True): + try: + if len(row) != 5: + raise ValueError("Некорректная строка tasklist CSV") + rows.append(ProcessIdentity(int(row[1]), row[0])) + except Exception as error: + errors.append(f"{type(error).__name__}: {error}") + except Exception as error: + errors.append(f"{type(error).__name__}: {error}") + return classify_snapshot("tasklist", rows, errors) + + +def check_processes(providers: Iterable[Callable[[], ProcessScan]] | None = None) -> ProcessCheck: + """UNKNOWN разрешает другой источник; только полноценный CLEAR открывает gate.""" + attempts = [] + sources = (scan_psutil, scan_powershell, scan_tasklist) if providers is None else providers + for provider in sources: + try: + scan = provider() + if not isinstance(scan, ProcessScan) or not isinstance(scan.state, ProcessState): + raise TypeError("Некорректный ответ проверки процессов") + except Exception as error: + scan = ProcessScan(ProcessState.UNKNOWN, getattr(provider, "__name__", "provider"), + errors=(f"{type(error).__name__}: {error}",)) + attempts.append(scan) + if scan.state in (ProcessState.CLEAR, ProcessState.BUSY): + return ProcessCheck(scan.state, tuple(attempts)) + return ProcessCheck(ProcessState.UNKNOWN, tuple(attempts)) + + +def require_clear(result: ProcessCheck) -> None: + if not isinstance(result, ProcessCheck) or result.state is not ProcessState.CLEAR: + detail = result.to_dict() if isinstance(result, ProcessCheck) else repr(result) + raise RuntimeError(f"Проверка процессов не дала CLEAR: {detail}")