Обеспечение приема и обработки радиосигналов на борту БАС - DRONE520/RF-BAS-COMMON GitHub Wiki

1. Введение

Беспилотная авиационная система (БАС) — это устройство, предназначенное для совершения полётов и решения различных задач в таких сферах, как аэрофотосъёмка, мониторинг, картографирование местности и другие. В рамках данной работы поставлена задача использования БАС в качестве разведчика РЭБ для исследования радиотехнической установки. Пусть есть место взлёта и место посадки. Очевидно, что БАС приземлится в зоне посадки с некоторой погрешностью. Предположим, что он успешно взлетел и движется по заданному маршруту в автоматическом или ручном режиме. Во время полета у него активируется режим исследования. На маршруте работают определенные станции, например, станции мобильной связи или РТС. Перемещаясь к зоне посадки, устройство постоянно отслеживает и сканирует частотный диапазон в соответствии с заданной конфигурацией. При обнаружении сигналов в определённом частотном диапазоне он фиксирует время их излучения и делает фотографии, чтобы более точно определить местоположение. Параметры радиосигналов также привязаны ко времени. То есть на определенной частоте, которую он зафиксировал, происходит сбор информации. Через секунду или пять секунд он повторяет этот процесс, находясь в зоне действия РТС, и, соответственно, фиксирует сигнал определенного уровня на той же частоте. Это продолжается до тех пор, пока уровень сигнала не опустится ниже порога (вблизи точки взлета или посадки), по которому его можно отсечь. Соответственно, в журнале будет несколько записей о том, что он пролетел в этой зоне и обнаружил некоторые уровни сигналов в определённые моменты времени на некоторой частоте. По мере движения БАС по маршруту он может попасть в другую зону РТС, в которой также нужно зафиксировать все данные. Далее можно извлечь из него информационный накопитель со всеми записанными данными.

Первоначально, надо спроектировать какое-то устройство, которое будет заниматься исследованием. Нужно получить радиосигнал и выполнить простейшие измерения параметров радиосигнала. Требуется вычислительный модуль, способный обрабатывать данные, поскольку на этом модуле будет функционировать всё программное обеспечение полезной нагрузки. Таким образом, основной целью работы является научить этот модуль обеспечению приема, обработки радиосигналов и записи параметров этого сигнала в журнал.

2. Прием и обработка радиосигналов на борту БАС

2.1 Аппаратура приема и обработки радиосигналов

HackRF One — это полудуплексный широкополосный программно-определяемый радиоприёмник (SDR), разработанный и выпущенный компанией Great Scott Gadgets. Устройство оснащено антенным портом SMA, портами SMA для ввода и вывода тактовых сигналов, а также портом USB 2.0. HackRF One способен как передавать, так и принимать сигналы в частотном диапазоне от 1 МГц до 6 ГГц, обеспечивая максимальную выходную мощность до 15 дБм в зависимости от выбранного диапазона. Устройство совместимо с широко используемым программным обеспечением для радиосвязи, таким как GNU Radio.

image
Рис. 1. HackRF One с подключённой антенной

NanoPi NEO (256Mb) — это одноплатный компьютер, разработанный компанией FriendlyARM на базе процессора Allwinner H3. Он оснащён четырьмя вычислительными ядрами Cortex A7 с тактовой частотой до 1,2 ГГц и работает под управлением операционной системы Ubuntu. Устройство имеет 256 МБ оперативной памяти DDR3 и поддерживает карты памяти microSD ёмкостью до 64 гигабайт. На верхней части платы расположены порты Ethernet, USB Type-A и microUSB (для питания DC 5V / 2A), а также слот для microSD.

image
Рис. 2. NanoPi NEO

2.2 Программное обеспечение приема и обработки радиосигналов

Базовое программное обеспечение

Программное обеспечение HackRF состоит из инструментов HackRF и библиотеки libhackrf. Инструменты HackRF представляют собой командные утилиты, которые позволяют взаимодействовать с устройством HackRF. Библиотека libhackrf является низкоуровневой и обеспечивает взаимодействие программного обеспечения на компьютере с HackRF.

Установка программного обеспечения HackRF на Linux: Ubuntu / Debian

sudo apt-get install hackrf

Libusb — это библиотека с открытым исходным кодом, которая предоставляет приложениям возможность управлять передачей данных на устройства USB и с них в системах Unix и не-Unix без необходимости использования драйверов в режиме ядра.

Установка libusb на Linux: Ubuntu / Debian

sudo apt-get install libusb-1.0-0-dev

ROS — предоставляет библиотеки и инструменты с открытым исходным кодом, которые помогают разработчикам программного обеспечения создавать приложения для роботов. ROS представляет собой набор программных фреймворков для разработки программного обеспечения для роботов, она предлагает услуги, предназначенные для работы с компьютерными кластерами. Эти услуги включают реализацию часто используемых функций, обмен сообщениями между процессами и управление пакетами.

  1. Ноды. ROS-нода представляет собой специализированный процесс, который взаимодействует с другими нодами. Ноды играют ключевую роль в программировании ROS, так как основная часть клиентского кода ROS состоит из нодов, которые выполняют действия на основе информации, полученной от других нодов. Они также могут отправлять данные другим нодам или обрабатывать запросы на выполнение действий через ROS-топики и ROS-сервисы.

  2. Топики. Топик – это именованная шина данных, по которой ноды отправляют и получают сообщения. Чтобы отправлять сообщения в произвольный топик, топик должен опубликовать сообщение в этом топике, а чтобы получать сообщения, он должен подписаться на этот топик. Модель «публикация/подписка» характеризуется анонимностью: ни один нодов не имеет информации о том, какие ноды отправляют или получают сообщения по определенному топику, а лишь знают, что он сам отправляет или получает сообщения по этому топику. Типы сообщений, передаваемых в рамках топиков, могут варьироваться и определяться пользователем. Содержимое этих сообщений может включать данные с датчиков, команды для управления двигателями, информацию о состоянии, команды для исполнительных механизмов или любые другие данные.

  3. Сервис. Сервис можно рассматривать как аналог функции, которую можно вызвать из одной ноды и обработать в другой. У сервиса есть имя, схожее с именем топика, а также два типа сообщений: запрос и ответ.

  4. Сервер параметров представляет собой общую базу данных для всех нодов, обеспечивающую доступ к статической или полустатической информации. Данные, которые редко изменяются и к которым обращаются нечасто, такие как расстояние между двумя фиксированными точками в окружающей среде или вес робота, являются подходящими для хранения на сервере параметров.

  5. Имена. Каждый топик, сервис или параметр обладает уникальным именем для своей идентификации. ROS-имя представляет собой иерархическую структуру, в которой символ / служит разделителем, подобно именам в файловой системе.

Одним из достоинств использования ROS является возможность распределения нодов между несколькими компьютерами в сети. Например, нода, отвечающая за распознавание объектов на изображении, можно запустить на более производительном компьютере, в то время как нода, управляющая модулем, можно разместить непосредственно на NanoPi NEO.

Установка ROS на Linux: Ubuntu / Debian

sudo apt install ros-noetic-desktop
sudo apt install python3-rosdep python3-rosinstall python3-rosinstall-generator python3-wstool build-essential
sudo rosdep init
rosdep update

Подробнее: Развертывание и применение ROS на микропроцессорной платформе

Разработанное программное обеспечение

Перед тем как начать работу, необходимо освоить использование SDR HackRF. Попробуем создать обнаружитель сигналов с помощью GNU Radio. GNU Radio Companion (GRC) — это графический интерфейс, который позволяет строить сигнальные графы для GNU Radio. Вся обработка сигналов в GNU Radio осуществляется с использованием схем, состоящих из отдельных блоков, каждый из которых выполняет всего одну операцию цифровой обработки сигнала. Данные передаются между блоками в различных форматах: комплексных или вещественных целых числах, с плавающей запятой или просто в виде данных.

Установка GNU Radio на Linux: Ubuntu / Debian

sudo apt-get install gnuradio

Блоки, из которых строится схема, делятся на следующие основные категории:

— Source. Источник сигнала, служит поставщиком цифровых данных, представляющих сигнал. Для SDR-радиоприемников это блоки osmocom Source, RTL-SDR Source. Источником или приемником может быть USB-донгл. В данном случае использовался HackRF (с блоком osmocom) с усилением промежуточной частоты (IF Gain): 20 и частотой дискретизации (samp_rate): 8 МГц.

Установка модуля osmocom Source на Linux: Ubuntu / Debian

sudo apt-get install gr-osmosdr

— Sink. Получатель сигнала, служит для конечной обработки приходящих данных - например для визуализации. QT GUI Time Sink - это графический приёмник на основе QT, который принимает наборы потоков с плавающей запятой или комплексных потоков и отображает их во временной области.

— GUI. Визуальные управляющие блоки - это движки (слайдеры), которые служат для плавного регулирования какой-либо величины (например изменения частоты настройки или уровня сигнала).

— Невизуальные блоки. Создают глобальные переменные, константы, опции. Служат для удобства управления проектом GNU Radio, чтобы какую-либо величину можно было задавать только в одном месте. Самый хороший пример - переменная samp_rate (блок Variable), которая автоматически создается вместе с новым проектом (samp_rate определяет частоту дискретизации по умолчанию для различных блоков цифровой обработки). Также к невизуальным блокам можно отнести блок Options, в котором определяются опции проекта (размер окна, заголовок, описание и т. д.).

Снимок экрана от 2024-12-09 13-10-49
Рис. 3. Схема в GNU Radio Companion

В качестве источника сигнала будет применяться высокочастотный генератор сигналов Keysight N9310A. Сгенерируем сигнал на частоте 2.402 ГГц и попробуем обнаружить его.

Снимок экрана от 2024-12-09 13-51-05 20241209_135129
Рис. 4. Отображение сигнала, получаемого с HackRF Рис. 5. Генерация сигнала на частоте 2.402 Гц

Можно наблюдать, что устройство активировалось. Сгенерируем сигнал в режиме развёртки (sweep mode) в диапазоне от 2.399 ГГц до 2.402 ГГц.

Снимок экрана от 2024-12-09 13-55-05 20241209_135350
Рис. 6. Отображение сигнала, получаемого с HackRF Рис. 7. Генерация сигнала в sweep mode с частотами от 2.399 ГГц до 2.402 ГГц

Таким образом, обнаружив изменения частоты, можно с уверенностью утверждать, что система функционирует корректно.

Далее необходимо написать программу RadioReceiver на C++ для взаимодействия с устройством HackRF, то есть обнаружитель, в задачи которого входит получение сигнала, обработка, выдача некоторых результатов обработки. Сигнал очень удобно представлять в комплексной форме, то есть I (синфазная) и Q (квадратурная) компоненты. У обнаружителя есть события, обнаружения и параметры, которые активируют его, а также параметры, фиксируемые в событии, например, уровень обнаружения.

Структура программы:

  • Detecter.h, Detecter.cpp (Обнаружитель\Детектор\Датчик)
  • general.h, general.cpp (Обработчик сигнала)
  • Receiver.h, Receiver.cpp (Приёмник)
  • hackrf.h (Заголовочный файл библиотеки libhackrf)
  • main.cpp (Точка входа в программу)
  1. Detecter. Включает в себя класс Detecter, который содержит массив данных vector data, и переменную для определения факта события LastResult. Для определения факта события используется виртуальный метод ProcessData(), который сравнивает уровень энергии с пороговым значением и в зависимости от результатов сравнения передаёт в переменную LastResult 0 или 1. Класс также содержит методы передачи в массив данных, получения массива данных и получение переменной события LastResult. В Detecter есть класс SignalEnergyDetecter, который определяет наличие помехи по уровню энергии сигнала.Threshold определяет переменную порога уровня сигнала, содержит метод для его установки и метод. Метод CalcEnergy(std::vector&source) из массива данных вычисляет уровень энергии как E = I^2 + Q^2.

  2. general. Метод ErrorHandler(int error) (обработчик ошибок для main и Receiver) выводит ошибку, которая определена в библиотеке hackrf. Метод RemoveConst(std::vector& target) вычитает постоянную составляющую из полученных компонент сигнала. Метод ToDouble(int8_t* target, int size) выполняет преобразование массива 8-битного целого числа в массив double. Метод PrintSignal(std::vector& target, const char* title) выводит I и Q составляющие.

  3. Receiver. Определяет класс Receiver, целочисленные переменные samplerate, frequency и IF определяют соответственно частоту дискретизации, центральную частоту и усиление промежуточной частоты. Методы для их установления присутствуют. Также Receiver содержит массив данных data, указатель на устройство HackRF, переменную последней ошибки устройства LastError, код ошибки LastResult, метод для его получения и метод получения массива данных. CloseDevice() завершает сеанс с устройством. Метод для приёма сигнала Receive() выполняется в следующем порядке: Инициализация -> Открытие сеанса устройства -> Установка параметров HackRF -> Начать передачу (на transfer callback) -> Закрыть устройство. На каждом шаге Receive срабатывает ErrorHandler, и если возникает ошибка, то устройство закрывается и возвращается код ошибки.

  4. main. Создаёт экземпляр класса Receiver (главное, чтобы был только один такой экземпляр). Далее вызываются для параметров Set-методы и запускается процесс передачи, после получения массива данных передача завершается, а массив выводится на экран.

Снимок экрана от 2024-12-09 13-08-43
Рис. 8. Получение I и Q компонент сигнала

На следующем этапе работы планируется установить на полётный контроллер систему под названием ROS, где можно использовать его API, которое позволит создавать события в системе и подписываться на них. Например, мы создаём события, на которые можно подписываться, т.е. две ROS-ноды, графическая и сигнальная. Когда произошло превышение по уровню, мы публикуем сигнальное событие. Если какой-то callback отображается в графике, то в этом callback делается ассоциация. Собственно, у нас в простейшем варианте должно происходить формирование журнала. Поэтому в дальнейшем необходимо на NanoPi попробовать развернуть ROS и сделать в нем ноды.

2.3 Интеграция полезной нагрузки БАС с полетным контроллером и станцией управления БАС

На следующем этапе работ интеграция полезной нагрузки БАС с полетным контроллером и станцией управления БАС будет осуществлена следующим образом:

ewqeqwe
Рис. 9. План по интеграции полезной нагрузки БАС с полетным контроллером и станцией управления БАС

Станция управления задает конфигурации. У Pixhawk есть передатчик, приемник, поэтому эти конфигурации должны попадать на NanoPi через Pixhawk, где они будут обеспечивать конфигурирование программного обеспечения оборудования в соответствии с этой конфигурацией. У Pixhawk есть разъемы RS-232 TELEM1 и TELEM2. К TELEM1 подключен передатчик, так что для NanoPi остаётся TELEM2. При подключении соответственно появится чисто физическая связь, поэтому надо организовать программную связь, то есть на стороне Pixhawk должно быть некое программное обеспечение, которое будет принимать данные от NanoPi и записывать их в UORB. И наоборот, информация, поступающая, например, с земли для NanoPi, будет использоваться для управления исследовательской нагрузкой. На стороне NanoPi что-то должно быть, что будет принимать и передавать. Для этого необходим ROS. Так как HackRF ничего не знает о процессе полёта, то ему нужна некая команда, которая будет содержать параметры конфигурации (на какую частоту, полосу и усиление), поэтому в первой записи должны содержаться настройки к HackRF. Дальше программы, которые работают, начинают управлять камерами Pixhawk, HackRF и так далее, собирая данные. Данные никуда не передаются, потому что они в большом объеме. Соответственно, они просто записываются в ROS, привязывая ко времени, однако стоит учитывать, что во времени они могут расходиться. Когда он вернется, можно эти данные из него просто считать.


05.03.2025 20250305_131903 Итак, что есть? Есть полетный контроллер, верно? Есть NanoPy, правильно? Значит, NanoPy и PIX соединены через разъем Telem. Здесь есть последовательный порт. Нужен журнал. Что с ним сделать? Мы должны записывать в него события. Какие характеристики должны быть у события? Первое — это время, с точностью до миллисекунд. Второе — координаты БПЛА. Третье — можно добавить ориентацию, углы поворота, это будет полезно. Ориентация также покажет курс, по которому он летит в данный момент. Четвертое — уровень сигнала. И, возможно, частота. А, и фотографию тоже стоит добавить. Если работаем с ROS, нужно создать собственное сообщение такого типа, да? Как-то его назвать. Они идут с определенными типами. Можно найти какое-то событие в качестве прототипа, где уже есть время. И может быть что-то из этого. Например, может существовать событие, время и координаты, которые можно добавить. Это будет вашим базовым классом. В C++ есть заголовочные файлы для таких сообщений, и, скорее всего, там будет какой-то класс или структура. Если это класс, то можно создать его наследника, а если это структура, то, возможно, одно из полей этой структуры станет внутренним полем вашей структуры. В принципе, это вполне осуществимо, и можно записывать данные туда. Однако возникает вопрос: кто будет сохранять эти данные на диск? потребуется разработать программу, которая будет работать в этом контексте, и это отдельная задача — выяснить, как она будет получать эти данные. Предположим, что они у неё уже есть. Давайте назовем её logger. Она будет записывать данные в ROS, верно? И у нас будет какая-то нода, например, saver или downloader, который будет подписчиком на эти события. Поскольку данные не сохраняются в ROS, эта нода должна получать события и записывать их в файл, например, на флешку. Флешка доступна для записи, так что это возможно. Если эти события будут поступать в ROS, логгер должен быть на них подписан и записывать их. Если же мы решим не использовать этот подход и будем получать данные из наших компонентов, то у нас останется только часть, связанная с публикацией и сохранением. Если мы от этого отказываемся, то можно сразу записывать файл. Однако стоит учитывать, что данные могут поступать очень быстро — например, за долю секунды может появиться 100 новых записей. Поэтому нужно либо буферизовать данные и записывать их в файл по очереди, чтобы избежать потерь, либо организовать параллельные потоки, выделяя отдельный поток для каждого события, куда будут отправляться данные. В этом случае потоки будут сохранять информацию, когда у них будет достаточно ресурсов. Важно понять, удастся ли получить эти данные через протокол MavLink. В принципе, всё это уже реализовано. Например, QGround Control именно этим и занимается. Он обрабатывает любые данные, которые поступают. Здесь также есть аналог ROS, который называется UORB. Он выполняет ту же функцию, выступая в роли менеджера, через который сообщения распределяются между издателями и подписчиками. В реальности у нас есть передатчик, подключенный к TLM, и приемник, который соединён с ноутбуком. На ноутбуке запущен QGround Control, который через Mavlink получает доступ к UORB и может извлекать все доступные данные. Ковшиков, например, пытается получить аналогичный доступ к этим данным. Я показал ему пример, и если он сможет его реализовать, то не потребуется ни ROS, ни что-то ещё. В любом случае, необходимо реализовать механизм сохранения данных. Сохранение должно быть организовано таким образом, чтобы впоследствии можно было расшифровать информацию. Соответственно, нужно разработать:

  1. Формат файла лога
  2. Написать код, который будет, например, заполнять структуру произвольными данными и записывать их в этот лог. Затем мы должны извлечь флешку, вставить её в ноутбук и написать программу, которая позволит извлечь данные оттуда и отобразить весь наш лог. В таком формате мы сможем увидеть список событий, к каждому из которых можно будет обратиться, чтобы просмотреть детали.

Это и есть основная задача. Поэтому можно начать разрабатывать код, который определит формат, а также пример программы для записи в журнал. Это можно сделать, пока Ковшиков занимается другими вопросами. Если ему удастся разобраться с этой задачей, мы сможем продвинуться вперед. Получение этих данных будет осуществляться, и соответствующий код их сохранит. Если же это не удастся, то мы интегрируем это в модуль, который будет работать автоматически.


3. Экспериментальное подтверждение приема и обработки радиосигналов на борту БАС

Следующий шаг заключается в получении результатов обнаружения сигнала на NanoPi. Для этого нужно собрать программу на NanoPi, используя либо кросс-компиляцию, либо инструмент сборки Ninja. Первоначально необходимо установить операционную систему на NanoPi. В нашем случае был использован образ для процессоров ARM Ubuntu 20.04.6 LTS. При работе с более старыми версиями Ubuntu могут возникнуть проблемы совместимости библиотеки libusb при сборке приложений. Надо записать образ ОС на microSD карту и вставить карту в слот для microSD. Далее нужно подключиться к NanoPi по сети с помощью сетевого сканера

sudo apt install nmap
nmap -sn 192.168.1.0/24
ssh [email protected].**
PI
Рис. 10. Установленная Ubuntu 20.04.6 LTS на NanoPi

Обновление индекса пакетов APT и обновление системы

sudo apt update
sudo apt upgrade

Для компиляции базового программного обеспечения, написанного на C и C++

sudo apt-get update
sudo apt-get install build-essential

Установка CMake на Ubuntu

sudo apt install cmake

Установка Ninja на Ubuntu

sudo apt install ninja-build

Установка Libusb на Ubuntu

sudo apt install libusb
sudo apt-get install libusb-1.0-0-dev

После того как всё нужное для работы установлено, необходимо клонировать репозиторий HackRF и репозиторий нашей программы RadioReceiver в отдельные директории. В директории ./hackrf/host/libhackrf/ будет находиться файл CMakeLists.txt. Для того чтобы собрать и скомпилировать библиотеку

sudo cmake
sudo make

После того как библиотека собралась в ./hackrf/host/libhackrf/src появятся 3 файла libhackrf.so, libhackrf.so.0, libhackrf.so.0.9.0. Их необходимо перенести в директорию ./RadioReceiver/MyHackrf/libs/comphackrf/build/ после чего собрать и скомпилировать ./RadioReceiver/MyHackrf/CMakeLists.txt. В ./RadioReceiver/MyHackrf/build появится приложение MyHackrf.

NanoPIWork
Рис. 11. Получение I и Q компонент сигнала на NanoPi

4. Экспериментальное подтверждение интеграции полезной нагрузки БАС с полетным контроллером и станцией управления БАС

Экспериментальное подтверждение интеграции полезной нагрузки БАС с полетным контроллером и станцией управления БАС предполагается на следующем этапе работ.

5. Заключение

В заключение можно отметить, что были успешно выполнены следующие задачи. Освоено взаимодействие с HackRF на стандартном компьютере с использованием GNU Radio Companion для обнаружения сигналов в заданном частотном диапазоне. Разработана программа для приёма и обработки сигналов, получаемых с HackRF, а также создан детектор, который определяет возникновение событий и различает их по уровню сигнала, отделяя от незначительных помех. Также были получены результаты по обнаружению и детектированию сигналов на NanoPi. В будущем предполагается создать журнал с применением системы ROS, а также интегрировать полезную нагрузку БАС с полетным контроллером и станцией управления БАС.

6. Источники

  1. Документация HackRF One. URL: https://hackrf.readthedocs.io/en/latest/hackrf_one.html
  2. Официальный сайт GNU Radio. URL: https://www.gnuradio.org/
  3. Friendly Elec Цiki NanoPi NEO. URL: https://wiki.friendlyelec.com/wiki/index.php/NanoPi_NEO
  4. Документация программного обеспечения HackRF. URL: https://hackrf.readthedocs.io/en/latest/installing_hackrf_software.html
  5. Официальный сайт Libusb. URL: https://libusb.info/
  6. Документация ROS. URL: https://docs.ros.org/
  7. Репозиторий на разработанную программу RadioReceiver. URL: https://github.com/Asevulon/RadioReceiver
  8. Официальный сайт Pixhawk. URL: https://pixhawk.org/
  9. Образы Ubuntu на Friendly Elec Wiki. URL: https://download.friendlyelec.com/NanoPiNEO
  10. Официальный сайт CMake. URL: https://cmake.org/
  11. Репозиторий HackRF. URL: https://github.com/greatscottgadgets/hackrf/tree/master


⚠️ **GitHub.com Fallback** ⚠️