GNU Radio Companion (далее для сокращения GRC) это графический инструмент для создания отображений сигналов и генерации исходного кода из графической схемы (flow graph) GRC-проекта (перевод [1]). Непонятные термины и сокращения см. в разделе "Словарик" статьи [11].
Новые функции, появившиеся начиная со стабильной версии GRC 0.70:
• Единая сборка - GRC теперь объединен с исходным кодом gnuradio. Если удовлетворены все зависимости, grc будут установлен вместе с gnuradio (см. разделы "Установка" и "Выполнение"). • Интеграция с рабочим столом - GRC может быть полностью встроен в графическое рабочее окружение, поддерживающее стандарты freedesktop (функции xdg-utils): иконки, mime-тип и элементы меню. • Генерация кода - GRC больше не использует один исполняемый файл для загрузки файла *.grc.xml и динамического запуска формы (flow graph). Вместо этого GRC использует шаблоны Cheetah для генерации исходного кода Python. GRC может генерировать исходный код как для WX GUI и не GUI flow graph, как и для иерархических блоков. • Документация - GRC может распаковать документацию для блоков GNU Radio напрямую из XML-файлов, сгенерированных системой Doxygen. Для поддержки этой функции Вам нужно будет сконфигурировать свою установку gnuradio с поддержкой doxygen. • Переменные - окно редактирования переменной прошлых релизов было заменено на блоки переменной. Блоки переменной видны в схеме GRC-проекта, и ведут себя как любые другие блоки за исключением того, что у них нет портов ввода/ввода (коннекторов in и out). Блок переменной привязывает уникальный идентификатор (ID, имя переменной) к определенному значению в GRC-проекте. У GRC также есть несколько графических блоков переменной, которые позволяют создавать элементы управления формы (WX GUI) с помощью слайдеров, полей ввода текста (text box), кнопок (button), выпадающих списков (drop down), зависимых кнопок выбора (radio button). • Определения блока - каждый блок в GRC имеет соответствующий файл описания XML, в котором содержатся параметры, порты ввода/вывода (IO ports) и шаблон для генерации кода. Для обеспечения будущей совместимости значение ID и имя каждого XML-файла полностью совпадает с именем блока GNU Radio. GRC при выполнении проекта проверяет на корректность все определения блоков, и завершит выполнение с ошибкой, если одно или несколько определений не прошли проверку. • Формат файла - когда меняются переменные и определения блока, внутренняя структура сохраненного файла flow graph также изменяется. Полезная возможность - GRC может автоматически преобразовать в новый формат файлы, сохраненные ранее в старых версиях GRC. К сожалению, преобразование не всегда может быть успешной на 100%. • Манипуляция блоками - теперь можно, не удаляя, запретить блок или перевести его в состояние перемычки. Блоки получили состояния enabled/disabled (разрешен/запрещен). По умолчанию блок разрешен (enabled). Когда блок запрещен (disabled), он закрашивается серым в схеме flow graph, и он будет игнорироваться валидатором flow graph и генератором исходного кода. Промежуточные блоки могут быть переведены в состояние перемычки (Bypass). Кроме того, блоки могут быть вырезаны, скопированы и вставлены редактором текущего flow graphs и в другой flow graph. Доступны стандартные операции отмены/возврата Undo/Redo (Ctrl+Z/Ctrl+Y). • Иерархические блоки - GRC может создавать иерархические блоки из встроенных блоков (см. секцию "Иерархические блоки").
[Системные требования]
GRC. Большинство (если не все) из этих требований можно найти в менеджере пакетов Вашего дистрибутива Linux.
GNU Radio. GRC объединен с текущим транком пакета gnuradio, и включен в релиз 3.2. Рекомендуется конфигурировать инсталляцию GNU Radio с поддержкой wx-python, usrp и audio. Однако будет работать любая конфигурация (см. примечание ниже). Инструкцию по сборке см. в [2].
Примечание: GRC позволит Вам сгенерировать flow graph с компонентами, которые не включены в Вашу локальную инсталляцию. Например, Вы можете генерировать сигнала из источника USRP, однако код при выполнении выдаст ошибку, если GNU Radio не сконфигурировано с поддержкой USRP.
Приложение GRC объединено с пакетом gnuradio, так что если следовать указаниям по его установке, то для установки GRC этого должно быть достаточно. Однако GRC не установится, если не был установлен один из требуемых компонентов. Установите любые недостающие компоненты и заново запустите процесс configure/install:
cmake ..
make
sudo make install
GRC должен появиться в списке сконфигурированных компонентов; если это не так, то читайте подробный вывод configure для выявления причины ошибок.
Установка документации. Чтобы можно было просматривать документацию по блокам в редакторе GRC, установите doxygen и сконфигурируйте configure gnuradio с поддержкой doxygen.
Установка иконок, типа Mime и элементов меню. Если Ваша операционная система поддерживает стандарты freedesktop.org (Gnome, KDE, XFCE), то Вы можете установить иконки (icons), тип mime (mime type) и элементы меню (menu items), встроенные в GRC. После установки GRC запустите следующую команду:
cd /libexec/gnuradio/
sudo ./grc_setup_freedesktop install
В самом начале статьи [3] есть ссылка на двоичные инсталляторы для 64-битных Windows 7/8/10. Они включают все нужные для Windows зависимости, настроенный дистрибутив Python, самые часто используемые драйверы приемников SDR и несколько блоков OOT.
Есть и другая сборка, которая включает GnuRadio, Pothos, CubicSDK и другие инструменты.
[Выполнение]
Для своего запуска GRC устанавливает несколько исполняемых файлов python в системные пути поиска (в Windows это переменная окружения %PATH%).
Редактор проекта (Flow Graph Editor) запускается командой:
gnuradio-companion
Советы по использованию:
• Добавление блока выполняется двойным кликом на блоке, выбранном в иерархии встраиваемых блоков (находится в правой области редактора GRC), или его перетаскиванием в область блоков проекта. • Блоки соединяются следующим образом: делается левый клик на одном из портов (in или out) одного блока, затем левый клик на одном из портов другого блока. • Удаление соединения: левый клик на соединении, нажатие клавиши Delete, или для удаления перетащите мышкой соединение. • Редактирование параметров блока: двойной клик на блоке в поле редактора flow graph. • Для быстрого изменения типа блока выделите блок (левым кликом) и нажимайте клавиши Up/Down. • Назначение горячих клавиш для основных функций показано в основном меню GRC. • Полностью симулируемые схемы flow graph (без блоков audio или usrp) при выполнении нагрузят CPU на 100%, и элементы GUI перестанут откликаться на действия пользователя. Такие схемы flow graph должны включать блок Misc->Throttle, чтобы уменьшить объем обрабатываемых данных.
[Переменные]
Переменные (Variable) связывают символические имена со значениями. В GRC переменная может определить глобальную константу, или переменная может использоваться совместно с GUI для управления работающим flow graph.
Variable Block. Блок переменной - базовый способ использовать переменную в GRC. Параметр ID у блока переменной определяет символическое имя переменной (symbolic name). Символическое имя должно состоять из алфавитных символов (цифры и подчеркивания в составе имени допускаются), и обязательно должно начинаться с буквы (не цифры). Для использования переменной просто введите символическое имя в поле параметра другого блока.
Variable Controls. Некоторые блоки снабжены callback-методами, позволяющими менять их параметры при выполнении flow graph. Variable controls в GRC используют переменные в комбинации с callback-методами для изменения этих параметров. Если у параметра есть callback-метод, то этот параметр будет подчеркнут в диалоге редактирования свойств блока. В блоках variable slider, variable text box и variable chooser предоставлены графические виджеты в качестве элементов управления интерфейса GUI - слайдеры/регуляторы, поля ввода текста, радиокнопки, выпадающие списки. Дополнительно блок variable sink принимает выборки из потока gnuradio, и записывает выборки в переменную.
String Evaluation. Строковые параметры проходят через две фазы обработки. Сначала GRC берет параметр "как есть". Если параметр не вычисляется как строковый тип данных, или вычисление терпит неудачу, то подразумевается, что у параметра должны быть неявные кавычки. В этом случае GRC вычислит параметр снова, но уже с кавычками; это возвратит строку с точной последовательностью кода, которая была введена в поле ввода параметра.
Для использования переменной внутри строки просто введите имя переменной в параметр: my_var. Если переменная не строка, то можно выполнить преобразование (cast) языка Python с помощью функции str: str(my_var). При этом работает стандартный строковый функционал Python: "My Var = " + str(my_var).
Примечание: параметры строкового типа также включают типы открытия и сохранения файла (file open и file save).
[Разработка фильтра]
В gnuradio многие блоки в качестве параметра принимают массив complex или real выборок сигнала. GNU Radio предоставляет пакет для генерации всех видов фильтров и их оконных функций. См. описание пакета firdes [4] из документации gnuradio.
Создайте новый блок "import", и введите следующие параметры импорта:
from gnuradio.filter import firdes
Примечание: большинство блоков с параметром taps автоматически импортируют модуль firdes. Вам только нужно использовать блок import, когда не будет вычисляться firdes.
Коэффициенты из файла. Предположим, что у Вас есть массив коэффициентов фильтра (filter taps), сохраненный в файл. Тогда Вы можете использовать его в GRC следующим образом. Создайте новый блок "import" и введите следующий параметр import:
Это приведет к чтению всего двоичного файла и обработки в нем каждой порции из 64 байт как комплектного числа. Используйте numpy.float32 для taps в формате real. См. подсказку numpy.fromfile для более продвинутого использования:
Требуемые аргументы:
file -- объект открываемого файла или строка, содержащая имя файла.
Аргументы ключевого слова:
dtype -- тип и порядок возвращенного массива (по умолчанию float)
count -- количество элементов для ввода (по умолчанию все)
sep -- разделитель между элементами в файле, если он текстовый (по умолчанию "")
Возвратит массив данных определенного типа из текстового или двоичного файла.
Аргумент file может быть открытым файлом, или строкой с именем файла, откуда
должны быть прочитаны данные. Если count == -1, то будет прочитан весь файл
целиком, иначе будет прочитано count элементов определенного типа. Если параметр
sep указан как "", то это значит, что читаются двоичные данные из файла
с использованием указанного типа dtype, иначе sep определяет разделитель между
отдельными элементами в текстовом файле. Значение dtype также используется
для определения размера и порядка элементов в двоичных файлах.
[Позиционирование элементов GUI по координатной сетке]
GRC предоставляет несколько графических элементов отображения данных (Scope Sink, FFT Sink, Waterfall Sink, Constellation Sink, ...) и графические органы управления для создания диаграмм схемы проекта (flow graph) wx-gui (Slider, Chooser, ...). Каждый из этих графических элементов имеет свой параметр Grid Position, предназначенный для точного позиционирования на форме работающего приложения GRC.
Параметр Grid Position это список из 4 целых чисел в форме row, column, row span, column span (строка, столбец, протяженность по строкам, протяженность по столбцам). Числа row и column задают позицию верхнего левого окна графического элемента. Самая малая позиция 0, 0 задает верхний левый угол координатной решетки (соответствует верхнему левому углу формы программы).
Если параметр решетки Grid Position оставить пустым, то графический элемент будет автоматически вставлен в позицию области последовательного вертикального размещения (vertical sizer). Область vertical sizer находится непосредственно над областью решетки (grid sizer). Если Вы не хотите добавлять какие-либо элементы в область vertical sizer, оставьте пустым параметр решетки (Grid Position).
3 и 4 параметры Grid Position (row span и column span), если они указаны, задают протяженность отображения графического элемента в решетке, или количество строк и столбцов, которое может занимать графический элемент по вертикали (по строкам решетки) и горизонтали (по столбцам решетки). Значение row span (третье число) задает количество строк вниз от позиции row, и значение column span (4 число) задает количество столбцов от позиции column. Таким образом, интервал (span) должен быть как минимум 1, 1, чтобы элемент GUI мог занять только одну ячейку координатной сетки формы.
Пример. Пользователь хочет разместить на форме Slider (движок регулятора), центрированный сразу над графикой Sink. Slider будет позиционироваться на 2 столбце верхней строки, и распространяться на 2 ячейки сетки. Sink будет позиционироваться на 2-й строке, и занимать горизонтальное пространство 3 ячейки от столбца 2. Получится следующее назначение параметров и результирующая координатная сетка.
Полученная форма GUI (позиции координатной сетки формы):
0,0 0,1 0,2 0,3 1,0 1,1 1,2 1,3 2,0 2,1 2,2 2,3
[Иерархические блоки]
GRC может создавать иерархические блоки из готовых, встроенных функциональных блоков. Иерархические блоки могут быть инстанцированы в другие flow graph. Код Python, сгенерированный из иерархического блока, сам по себе может использоваться для не-GRC схем flow graph. В создании иерархического блока используется 4 важных блока: блок options, блоки parameter, коннектор источника (pad source) и коннектор получателя (pad sink) данных.
Блок Options. Чтобы создать иерархический блок, должны быть правильно установлены параметры блока options. Параметр ID блока options устанавливает генерируемое имя модуля Python для иерархического блока, и он должен быть уникальным среди всей библиотеки блоков (как встроенных, так и созданных пользователем). Параметр Title устанавливает отображаемое имя блока. Параметр Generate Options должен быть установлен в Hier Block. Параметр Category устанавливает категорию нового блока. Эта категория может быть существующей категорией в окне выбора блоков (список категорий блоков и их имен в виде дерева, находящийся в правой части окна редактора GRC), либо быть новой категорией. Категории могут быть вложенными друг в друга путем указания последовательности имен, разделенных слешем, например Custom/Filters. Для того, чтобы поместить блоки в корень категорий (root category), укажите одиночный слеш "/" (пустой параметр Category скроет Ваш блок).
Блоки Parameter. Блоки параметров указывают переменные в Вашем иерархическом блоке, которые должны конфигурироваться на верхнем уровне блока. Блоки параметра работают наподобие блоков переменной (встроенный блок Variable) с несколькими исключениями: блоки параметров не могут зависеть от других блоков параметров. Блоки параметров имеют параметр метки Label, используемый с целью отображения какой-либо информации. Блоки параметра занимают место блока переменной, не пытайтесь создать блок переменной с таким же ID, как и у блока параметра.
Блоки Pad Source и Pad Sink. Это коннекторы для создания входов и выходов иерархического блока. У блоков pad конфигурируется тип данных, длина вектора и количество портов. Блок flow graph может иметь чаще всего один коннектор источника (pad source, выход) и один коннектор получателя (pad sink, вход). Иерархический блок может иметь один pad sink и не иметь при этом pad source, или может иметь один pad source и не иметь pad sink, однако должен быть хотя бы один блок pad.
Создание и инстанцирование:
• Начните создание блока с нуля путем создания нового (пустого) flow graph. • Настройте блок Options, как было указано ранее, с заполнением его параметров ID, Title, Generate Options и Category. • Добавьте блоки Parameter для всех переменных, которые Вы хотите конфигурировать (управлять ими) извне блока. • Создайте как минимум один one pad source и/или один pad sink, который соответствовал бы типу ввода/вывода блока, чтобы к нему можно было подключать другие блоки. • После завершения кликните на кнопку "Generate the flow graph" (или нажмите F5, что соответствует меню Run -> Generate), и после этого закройте и снова откройте GRC. • Новый созданный иерархический блок появится в окне выбора блоков (правая часть окна GRC). • Добавьте иерархический блок в свой flow graph точно так же, как и любые другие блоки.
Замечания:
• Поле изменений, сделанных в иерархическом блоке, необходимо его сгенерировать заново. После этого надо закрыть и повторно открыть GRC перед тем, как использовать измененный иерархический блок. • Параметр ID иерархического блока должен быть глобально уникальным (не должно быть блоков с одинаковым ID, ни встроенных, ни пользовательских). Если у двух блоков одинаковый ID, то последний из генерируемых перезапишет результат генерации другого. • Пользовательские иерархические блоки могут инстанцировать другие пользовательские иерархические блоки. Однако нельзя допускать инстанциации блока самим собой!
[Добавления пользовательских блоков]
Каждый блок в GRC соответствует XML-файлу, который описывает параметры блока, его входы, выходы и другие атрибуты. Добавление пользовательского блока (custom block) это просто вопрос создания одного из XML-файлов определения блока. Есть несколько важных моментов:
• Блок должен быть доступен из путей поиска python. Это означает, что к блоку можно обратиться через оператор import. • Блок придерживается следующей модели диаграммы: в нем есть параметры, входы и выходы. Если блок требует прослушивающие потоки определенного вида, или специальные callback-методы для перемещения данных (такие как пакетная обработка blks2), то такой блок не может использоваться в GRC (если эта "специальная" функциональность не может инкапсулироваться в блок, безопасный для использования в блок-схеме GRC). • Если у GRC отсутствует определения блока, находящегося в настоящий момент в транке, или в одном из определений блока отсутствует функционал, то сообщите об этом разработчикам. Определения блоков в транке GRC должны оставаться синхронными с действующими блоками GNU Radio.
Создание XML-определения блока. Самый лучший способ научиться создавать xml-файл - разобрать его рабочий пример. Для этого просмотрите определения блоков (source:grc/blocks), поставляемые вместе с GRC, и откройте содержимое нескольких файлов. В сущности все определения блока структурируются следующим образом (в этом примере создается блок с 2 параметрами, одним входом и двумя выходами):
My Block Name
my_package_my_block_ff
Filters
from gnuradio import my_package
my_package.my_block_ff($param1, $param2)
set_param1($param1)
Parameter 1
param1
real
Parameter 2
param2
1
int
in
float
part
out
float
out
float
Важные замечания:
• Важен порядок следования тегов, если теги не организованы правильно, то блок не пройдет проверку (подробнее см. block.dtd [5]). • Теги name задают текст метки для блока, параметров и портов. • Теги key это уникальные идентификаторы, в которых недопустимы пробелы. Key блока должен быть глобально уникальным среди всех блоков в GRC. Key параметров должны быть уникальными только внутри блока. • Тег category это путь в стиле unix, представляющий размещение блока внутри окна выбора блоков (правая область окна GRC). Путь может создавать новую категорию (Custom) или представлять категорию, вложенную в уже существующую (Filters/Custom). Чтобы поместить блок в корневую (root) категорию, просто используйте для пути одиночный слеш (/). • Тег import (их может быть несколько) должен быть допустимым оператором импорта python для модуля, содержащего Ваш блок. • Тег make содержит код, необходимый для конструирования Вашего блока. Этот код в сущности является шаблоном Cheetah, встроенным в тег xml. При генерации кода шаблон выполняет подстановку текста в параметры "$". Использование дополнительных возможностей см. в документации по шаблонам Cheetah [6]. • Тег callback регистрирует метод установки (set-method) из Вашего пользовательского блока. Как только set-method зарегистрирован, он может быть вызван во время выполнения проекта (runtime), когда изменяется переменная. Может быть любое количество тегов callback, один для каждого set-method Вашего блока. Или тегов callback может не быть, если они не нужны. • Для тегов param чаще всего используются значения тегов type: complex, real, int, complex_vector, real_vector, int_vector, string и raw. Тип raw позволяет использовать любое значение без выполнения проверки типа. Тип real должен использоваться для одиночной или двойной точности (single, double precision) чисел с плавающей запятой. Тип int должен использоваться для типов long, int, short и char. • Тег hide управляет, как параметр отображается в GRC. Может быть либо none, либо part (показывается в окне диалога, не в блоке canvas), либо all. • Тег sink представляет входной порт, и тег source представляет выходной порт. Разрешенные значения для тегов type: complex, float, int, short и byte. Для портов с длиной вектора после тега type указывается тег vlen. • В случае, когда Вы хотите создать определение блока, как это делается для FECAPI (Forward Error Correction API), тег key должен начинаться с префикса variable_, чтобы он корректно работал в GRC.
Примеры определения блока:
• Простой пример, "Complex to Real" [7]. • Несколько callback: "Costas Loop" [8]. • Пример Vlen: "Throttle" [9]. • Advanced Make: "FFT" [10].
Установка XML-определения блока. Есть несколько методов, чтобы указать GRC на Ваш новый XML-файл.
Метод 1: расположение в иерархии по умолчанию. Создайте файл _.xml_ внутри /.grc_gnuradio/* Вашей домашней директории. Если эта директория не существует, то создайте её (командой mkdir ~/.grc_gnuradio/).
Метод 2: файл конфигурации. Создайте или отредактируйте ~/.gnuradio/config.conf, и добавьте в него следующие строки:
[grc] local_blocks_path=/path/to/my/blocks
В local_blocks_path может быть несколько путей, отделенных друг от друга двоеточиями:
Метод 3: переменная окружения. Установите переменную окружения GRC_BLOCKS_PATH на путь, в котором содержится Ваша обертка пользовательского блока. GRC_BLOCKS_PATH может содержать несколько путей, отделенных друг от друга двоеточиями:
GRC_BLOCKS_PATH=/path/to/blocks1:/path/to/blocks2
[Ссылки]
1. GNU Radio Companion site:wiki.gnuradio.org. 2. Building GNU Radio manually from source site:wiki.gnuradio.org. 3. Windows Installation site:wiki.gnuradio.org. 4. gr::filter::firdes Class Reference site:gnuradio.org. 5. GNU Radio block.dtd site:github.com. 6. Cheetah User’s Guide site:cheetahtemplate.org. 7. GNU Radio "Complex to Real" site:github.com. 8. digital_costas_loop_cc.block site:github.com. 9. gnuradio blocks_throttle.block site:github.com. 10. gnuradio fft_fft_vxx.block site:github.com. 11. GNU Radio, краткий справочник.