diff --git a/.gitignore b/.gitignore index 87f4802..31488cc 100644 --- a/.gitignore +++ b/.gitignore @@ -29,9 +29,24 @@ __pycache__/ venv/ env/ -# Необработанные данные и IQ-записи +# Необработанные данные и IQ-записи. +# Правило закрывает крупные записи отсчётов и видео: они воспроизводятся +# заново и в историю не помещаются. data/raw/ +# Исключения: исходные изображения — это входные данные лабораторных, а не +# результат. Без них Lab007, Lab009, Lab011 и Lab012 не запускаются, поэтому +# они хранятся в репозитории. Суммарно около 1 МБ. +!data/raw/lab007_source.jpg +!data/raw/lab009_source.jpg +!data/raw/lab011_scene.jpg +!data/raw/lab012_safety_scene.jpg + +# Метаданные и спектр записи Lab024a: сама запись отсчётов не хранится, +# поэтому они оставлены как след проведённого измерения. +!data/raw/lab024a_pluto_rx_100mhz.json +!data/raw/lab024a_pluto_rx_100mhz_spectrum.png + # Временные файлы редакторов *.tmp *.temp diff --git a/README.md b/README.md index dbbeab6..36defad 100644 --- a/README.md +++ b/README.md @@ -4,330 +4,169 @@ **SDR Rover Link** — учебно-исследовательский проект по разработке цифрового радиоканала для наземного робототехнического комплекса с использованием программно-определяемого радио — SDR, Software Defined Radio. -Проект должен пройти полный путь от передачи простого текстового пакета до передачи телеметрии и отдельных JPEG-изображений через реальный радиоканал. +Проект должен пройти полный путь от передачи простого текстового пакета до передачи телеметрии и изображений через реальный радиоканал. -Основная задача проекта — не только получить работающую систему, но и последовательно изучить все этапы цифровой радиосвязи: - -- формирование данных; -- разбиение данных на пакеты; -- контроль целостности; -- исправление ошибок; -- цифровую модуляцию; -- формирование IQ-сигнала; -- передачу через SDR; -- приём и демодуляцию; -- восстановление исходных данных. +Основная задача — не только получить работающую систему, но и последовательно изучить все этапы цифровой радиосвязи: формирование данных, разбиение на пакеты, контроль целостности, исправление ошибок, цифровую модуляцию, формирование IQ-сигнала, передачу через SDR, приём, демодуляцию и восстановление исходных данных. --- ## 2. Целевой сценарий -Разрабатываемая система предназначена для исследовательского наземного ровера. - -Целевые требования: - | Параметр | Требование | |---|---| | Дальность связи | до 10 км | | Скорость ровера | до 25 км/ч | | Прямая радиовидимость | может отсутствовать | -| Рабочие частоты | ниже 350 МГц | -| Основной тип данных | телеметрия и отдельные изображения | +| Рабочий диапазон | 200–250 МГц, см. Запись 018 журнала | +| Основной тип данных | телеметрия, команды и изображения | | Формат изображения | JPEG | -| Частота передачи изображений | отдельные кадры, не видеопоток | | Действие при потере связи | безопасная остановка ровера | -Дальность 10 км без прямой видимости является целевым исследовательским требованием, а не гарантированной характеристикой первой версии системы. +Дальность 10 км без прямой видимости — целевое исследовательское требование, а не гарантированная характеристика первой версии. --- ## 3. Почему не используется обычное FPV-видео -Типовые FPV-системы работают преимущественно в диапазонах 2,4 и 5,8 ГГц. +Типовые FPV-системы работают в диапазонах 2,4 и 5,8 ГГц. Для наземного робота это плохо: велики потери у поверхности земли, сильное затенение рельефом и растительностью, а главное — на таких частотах практически нет дифракции, поэтому за препятствием связь пропадает. -Для наземного робота такие диапазоны имеют ряд ограничений: +В этом проекте вместо непрерывного видеопотока передаются отдельные сжатые изображения, что резко снижает требуемую скорость канала. -- высокие потери при работе у поверхности земли; -- затенение рельефом, зданиями и растительностью; -- быстрое ухудшение изображения при слабом сигнале; -- высокая загруженность распространённых диапазонов; -- зависимость от постоянного широкополосного видеопотока. +--- -В этом проекте вместо непрерывного видео предполагается передавать отдельные сжатые изображения. +## 4. Текущее состояние -Пример: +**Выполнено:** лабораторные Lab001–Lab041. Пройден путь от структуры пакета до сеансов связи с защитой от пакетов предыдущего сеанса. -```text -Камера - ↓ -JPEG-изображение - ↓ -Разбиение на пакеты - ↓ -Передача через SDR - ↓ -Сборка изображения на наземной станции +Что реализовано и проверено: + +- пакетный протокол с CRC32, фрагментация и сборка изображений; +- модуляция и демодуляция BPSK, формирующий фильтр, кадровая синхронизация, оценка и коррекция ухода несущей; +- блочное исправление стираний над GF(256), перемежение, подбор параметров; +- приоритетное обслуживание команд, телеметрии и видео; +- двухступенчатая безопасная остановка, сторожевой таймер, постоянное аварийное намерение, безопасный сброс; +- идентификаторы сеанса, безопасный запуск, отклонение пакетов предыдущего сеанса. + +**Что ещё не сделано:** передатчик ни разу не включался. Весь тракт проверен на моделях и на приёме, но не в эфире. + +**Ближайшая работа:** Lab042 — передача JPEG через кабельную петлю на одном PlutoSDR. Техническое задание: [docs/lab042_hardware_loopback_spec.md](docs/lab042_hardware_loopback_spec.md). + +Хронология решений и результатов: [PROJECT_LOG.md](PROJECT_LOG.md). + +--- + +## 5. Оборудование + +| Позиция | Состояние | +|---|---| +| **Pluto+** — приёмопередатчик, чип AD9361, 70 МГц – 6 ГГц | есть | +| RTL-SDR — приёмный донгл | есть | +| Аттенюатор AT30S, 30 дБ, SMA | есть | +| Кабели SMA, штыревые антенны | есть | +| Усилитель мощности около 1 Вт | планируется после первых испытаний | +| Raspberry Pi как бортовой вычислитель | планируется | + +Устройство подключается по USB и появляется в системе как сетевой адаптер с адресом `192.168.2.1`. + +**Проверять связь с Pluto командой `ping` бесполезно.** При активном VPN трафик уходит в туннель, и «успешный» отклик приходит даже от несуществующего адреса. Достоверна только успешная установка контекста `iio.Context("ip:192.168.2.1")`. + +--- + +## 6. Установка окружения + +Расчётная часть работает на компьютере без SDR: + +```bash +python -m pip install -r requirements.txt ``` -Такой подход позволяет существенно снизить требуемую скорость радиоканала. +Для лабораторных, работающих с устройством, дополнительно: + +```bash +python -m pip install -r requirements-hardware.txt +``` + +Версии зафиксированы по проверенному окружению, Python 3.13. --- -## 4. Текущее оборудование +## 7. Как запускать -### SDR-оборудование +**Быстрые проверки ядра** — секунды, оборудование не нужно: -- RTL-SDR — приёмник; -- ADALM-PlutoSDR — приёмопередатчик, ожидается поступление; -- HackRF One — может временно использоваться при необходимости. +```bash +python -m pytest tests/ -q +``` -### Вычислительное оборудование +**Дешёвый шлюз** — синтаксис, импорт `protocol`, функциональные проверки лабораторных: -- компьютер под управлением Windows; -- Raspberry Pi — планируется для установки на ровер; -- бортовой вычислитель ровера — будет выбран позднее. +```bash +python tools/quick_gate.py +``` -### Программное обеспечение +**Лабораторный эксперимент** — минуты, пишет результаты в `data/processed/`: -- Python 3.12; -- Anaconda; -- Spyder; -- Git; -- GNU Radio — будет установлен на следующем этапе; -- libiio и драйверы PlutoSDR — будут установлены после получения устройства. +```bash +python -m experiments.lab041_session_restart_safety +``` --- -## 5. Предварительно рассматриваемые диапазоны - -В рамках проекта рассматриваются: - -- 27 МГц; -- 50 МГц; -- 144 МГц; -- другие разрешённые для лабораторных испытаний частоты ниже 350 МГц. - -Конкретный диапазон будет выбран после анализа: - -- доступной полосы; -- требований законодательства; -- размеров антенны; -- потерь распространения; -- уровня внешних помех; -- возможностей выходного радиочастотного тракта; -- допустимой мощности передачи. - -Передача по эфиру должна выполняться только на разрешённых частотах и с соблюдением допустимой мощности. Первые опыты следует проводить через аттенюатор, эквивалент нагрузки или в экранированной лабораторной конфигурации. - ---- - -## 6. Основные этапы проекта - -### Этап 0. Подготовка среды - -- создание репозитория; -- настройка Git; -- настройка Python и Spyder; -- подготовка структуры каталогов; -- ведение документации. - -### Этап 1. Пакетный протокол - -- структура пакета; -- типы сообщений; -- порядковый номер пакета; -- длина данных; -- CRC; -- кодирование и декодирование. - -### Этап 2. Виртуальный канал - -- передача пакетов между Python-программами; -- имитация потерь; -- имитация повреждения битов; -- измерение числа ошибочных пакетов. - -### Этап 3. Передача файлов - -- разбиение файла на фрагменты; -- нумерация фрагментов; -- подтверждение приёма; -- повторная передача; -- сборка исходного файла. - -### Этап 4. Передача изображений - -- загрузка JPEG; -- разбиение JPEG на пакеты; -- передача через виртуальный канал; -- восстановление изображения; -- обработка потерянных фрагментов. - -### Этап 5. Физический уровень - -- BPSK; -- QPSK; -- формирование символов; -- IQ-сэмплы; -- синхронизация; -- фильтрация; -- оценка BER и PER. - -### Этап 6. PlutoSDR - -- подключение устройства; -- передача несущей; -- передача тестовой последовательности; -- передача цифрового пакета; -- приём сигнала RTL-SDR или вторым SDR. - -### Этап 7. Радиоканал передачи изображений - -- передача JPEG через SDR; -- измерение времени доставки; -- испытания при различных уровнях сигнала; -- испытания при наличии помех; -- подбор скорости и модуляции. - -### Этап 8. Полевые испытания - -- испытания на малой мощности; -- испытания на малой дистанции; -- постепенное увеличение расстояния; -- испытания с ретранслятором; -- испытания на наземном ровере. - ---- - -## 7. Структура репозитория +## 8. Структура репозитория ```text SDR_Rover -│ -├── README.md -├── docs -├── protocol -├── rover -├── ground_station -├── gnuradio -├── tests -└── tools +├── protocol/ реализация протокола и радиотракта +├── experiments/ лабораторные Lab001–Lab041 +├── tests/ быстрые автоматические проверки +├── tools/ вспомогательные программы и шлюз +├── docs/ технические задания и исследования +├── data/ исходные данные и результаты +├── rover/ пока пусто +├── ground_station/ пока пусто +└── gnuradio/ пока пусто ``` -### `docs` - -Документация, лабораторные работы, схемы и отчёты. - ### `protocol` -Реализация пакетного протокола: +Ядро системы. Пакет с CRC32, фрагментация изображений, кадр канала, исправление стираний, приоритеты, аварийная логика, сеансы связи, примитивы BPSK-радиотракта. -- структура пакета; -- CRC; -- кодирование; -- декодирование; -- типы сообщений. +### `experiments` -### `rover` - -Программы, которые будут работать на борту ровера: - -- получение изображения; -- сжатие JPEG; -- передача телеметрии; -- формирование радиопакетов. - -### `ground_station` - -Программы наземной станции: - -- приём пакетов; -- сборка изображений; -- отображение телеметрии; -- управление передачей. - -### `gnuradio` - -Схемы GNU Radio Companion: - -- передатчик; -- приёмник; -- BPSK-модем; -- QPSK-модем; -- тестовые генераторы. +Лабораторные работы. Это исследовательские программы: они моделируют канал, выполняют сотни повторов, строят CSV, графики и отчёты. **Быстрыми тестами они не являются.** При импорте создают каталоги и пишут файлы, поэтому импортировать их не следует — для повторного использования кода служит `protocol/`. ### `tests` -Автоматические и лабораторные тесты. +Настоящие быстрые проверки `protocol/`. Выполняются за доли секунды, оборудования не требуют, запускаются через `pytest`. -### `tools` +### `rover`, `ground_station`, `gnuradio` -Вспомогательные программы: - -- анализ пакетов; -- генераторы тестовых данных; -- построение графиков; -- анализ журналов. +Каталоги созданы под будущую прикладную часть и пока пусты. Бортовая программа ровера, программа наземной станции и схемы GNU Radio появятся после того, как радиоканал заработает в эфире. --- -## 8. Принципы разработки +## 9. Данные -В проекте применяются следующие правила: +- `data/raw` — исходные данные. Крупные записи отсчётов и видео в репозиторий не помещаются, исходные изображения лабораторных хранятся. +- `data/processed` — результаты лабораторных: CSV, отчёты и графики. + +**Ограничение воспроизводимости.** Исходное видео `data/raw/lab026_rover_source.mp4` (около 7,8 МБ) в репозитории не хранится. Без него Lab026 и Lab027 не запускаются, файл нужно получить отдельно. + +--- + +## 10. Принципы разработки 1. Каждый новый термин сначала объясняется, затем используется. -2. Каждый этап должен завершаться работающим результатом. +2. Каждый этап завершается работающим результатом. 3. Радиоканал и пакетный протокол разрабатываются отдельно. 4. Код проверяется автоматическими тестами. -5. Все существенные решения фиксируются в документации. +5. Все существенные решения фиксируются в журнале. 6. Сложность увеличивается постепенно. -7. Испытания по эфиру начинаются только после проверки через виртуальный канал. +7. Испытания по эфиру начинаются только после проверки через модель. 8. Передатчик сначала проверяется через аттенюатор или эквивалент нагрузки. +9. **Каждое число в отчёте должно вычисляться из измерений текущего запуска.** Перенесённые из других лабораторных величины сопровождаются указанием источника. Вписанные вручную результаты недопустимы. ---- - -## 9. Текущий статус - -Выполнено: - -- установлен Python; -- установлена Anaconda; -- выбран Spyder; -- установлен Git; -- создан локальный Git-репозиторий; -- создана базовая структура каталогов. - -Следующая задача: - -> Создать первый Python-модуль пакетного протокола и передать сообщение через виртуальный канал без SDR-оборудования. - ---- - -## 10. Ближайший контрольный результат - -Первая рабочая версия должна выполнять следующий цикл: - -```text -Текстовое сообщение - ↓ -Преобразование в байты - ↓ -Формирование пакета - ↓ -Добавление CRC - ↓ -Имитация радиоканала - ↓ -Проверка CRC - ↓ -Восстановление сообщения -``` - -Первое тестовое сообщение: - -```text -HELLO SDR -``` +Девятое правило добавлено после аудита достоверности, см. Запись 017 журнала. --- @@ -337,4 +176,4 @@ HELLO SDR НИЯУ МИФИ -2026 \ No newline at end of file +2026 diff --git a/data/processed/lab041/lab041_report.txt b/data/processed/lab041/lab041_report.txt index 140aad4..f8fdbb2 100644 --- a/data/processed/lab041/lab041_report.txt +++ b/data/processed/lab041/lab041_report.txt @@ -324,7 +324,7 @@ Lab041 — сеансы связи, безопасный запуск и защ Созданные файлы - protocol/control_messages.py - protocol/session_state.py -- tests/lab041_session_restart_safety.py +- experiments/lab041_session_restart_safety.py - data/processed/lab041/lab041_summary.csv - data/processed/lab041/lab041_session_metrics.csv - data/processed/lab041/lab041_rejection_metrics.csv diff --git a/experiments/lab041_session_restart_safety.py b/experiments/lab041_session_restart_safety.py index 3e84116..e1b2e1b 100644 --- a/experiments/lab041_session_restart_safety.py +++ b/experiments/lab041_session_restart_safety.py @@ -2,13 +2,10 @@ from __future__ import annotations -import ast import csv from dataclasses import asdict, dataclass from enum import IntEnum -import inspect from pathlib import Path -import re from typing import Iterable import cv2 @@ -1486,12 +1483,11 @@ def validate_outputs( assert not any(path.suffix.lower() in forbidden for path in actual) assert not any(path.name == "__pycache__" for path in OUTPUT_DIRECTORY.rglob("*")) - source = inspect.getsource(save_plots) - tree = ast.parse(source) - for node in ast.walk(tree): - if isinstance(node, ast.Call) and isinstance(node.func, ast.Attribute) and node.func.attr in {"set_title", "set_xlabel", "set_ylabel"}: - if node.args and isinstance(node.args[0], ast.Constant) and isinstance(node.args[0].value, str): - assert re.search("[А-Яа-яЁё]", node.args[0].value) + # Прежде здесь лабораторная разбирала собственный исходный код, чтобы + # убедиться, что подписи на графиках русские. Проверка снята: она + # относится к оформлению, а не к корректности модели, и превращала + # эксперимент в анализатор своего же текста. Подписи видны на готовых + # PNG и проверяются при просмотре результатов. def main() -> None: diff --git a/requirements-hardware.txt b/requirements-hardware.txt new file mode 100644 index 0000000..7b7dc2c --- /dev/null +++ b/requirements-hardware.txt @@ -0,0 +1,20 @@ +# SDR Rover Link — аппаратное окружение. +# +# Нужно только для лабораторных, работающих с PlutoSDR: +# Lab024a, Lab024b, Lab025 и всё, начиная с Lab042. +# +# Устанавливается поверх расчётного окружения: +# python -m pip install -r requirements.txt +# python -m pip install -r requirements-hardware.txt +# +# Проверено 10 августа 2026 года на устройстве +# Analog Devices PlutoSDR Rev.C (Z7010-AD9361), прошивка v0.32, +# подключение по USB как RNDIS-адаптер, адрес ip:192.168.2.1. +# +# Замечание по диагностике: наличие связи с устройством проверяется +# только успешным подключением через iio.Context. Команда ping и проверка +# открытых портов недостоверны — при активном VPN трафик уходит в туннель +# и создаёт видимость доступности несуществующего адреса. + +pyadi-iio==0.0.21 +pylibiio==0.25 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..18aedab --- /dev/null +++ b/requirements.txt @@ -0,0 +1,21 @@ +# SDR Rover Link — расчётное окружение. +# +# Достаточно для запуска быстрых проверок (pytest), всех расчётных +# лабораторных и построения графиков. Оборудование не требуется: +# проект поднимается на компьютере без SDR. +# +# Установка: +# python -m pip install -r requirements.txt +# +# Версии зафиксированы по фактически проверенному окружению +# от 10 августа 2026 года, Python 3.13.1. +# +# Аппаратные лабораторные (Lab024, Lab025, Lab042 и далее) требуют +# дополнительно requirements-hardware.txt. + +numpy==2.2.6 +scipy==1.18.0 +matplotlib==3.11.1 +opencv-python==4.12.0 +Pillow==12.0.0 +pytest==9.1.1