Gnuradio(3.10)创建OOT自定义模块--USRP X410软件无线电平台开发

本文主要是介绍Gnuradio(3.10)创建OOT自定义模块--USRP X410软件无线电平台开发,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 平台环境
  • 一、OOT模块(Out-Of-Tree Module)
  • 二、创建OOT模块
    • 1.利用gr_modtool创建模块框架文件
    • 2.编写一个C++模块(名称为square_ff)
    • 3.在OOT module中继续添加一个模块(名称为square2_ff)
  • 三、运行测试
  • 总结


平台环境

环境平台:PC win10 + 虚拟机Vmware15.5(Ubuntu21.04)+ Gnuradio 3.10.0.0git

一、OOT模块(Out-Of-Tree Module)

OOT模块是指Gnuradio中并不包含的模块资源,用户根据需求自己定义来制作。编写OOT模块的方法多种,推荐采用gr_modtool工具(安装Gnuradio时默认已安装)。

二、创建OOT模块

参考链接:https://wiki.gnuradio.org/index.php/OutOfTreeModules

1.利用gr_modtool创建模块框架文件

执行指令如下:
$ gr_modtool newmod howto
在这里插入图片描述
创建文件夹名称为"gr-howto"的模块工程文件如上图,gr-howto文件夹中包含若干个文件,其中lib和include文件存放着C++文件和头文件,python文件夹存放单元测试文件和python模块文件。对于Gnuradio 3.8及以前版本,还会包含swig文件,其内部文件负责着C++和python文件的接口和联合封装,在3.9后的版本中,不再使用swig,而是采用pybind11,相关文件存放在python的binding文件夹里。
app文件夹存放已经装载在Gnuradio和编译完成的模块应用文件;grc文件中存放着一个关键的yml文件(GR3.8版本前为xml文件),是已经编辑好的OOT模块与Gnuradio接口桥梁。
OOT涉及关键文件关系如下图:
在这里插入图片描述

2.编写一个C++模块(名称为square_ff)

(1)通过gr_modtool工具添加block相关文件。
举例设计一个block,作用是将输入的single float数据计算平方,再输出single float数据,block命名为square_ff,尾缀的"ff"表示输入输出参数都是float(‘f’)。该模块作为gr-howto Python module目录下的模块之一,python调用该block时可以如下语句:
Import howto
Sqr = howto.square_ff()
通过 gr_modtool 工具创建模块文件,依次输入指令如下图:
在这里插入图片描述
注意Gnuradio版本不同,文件结构也有区别(左侧图为Gnuradio3.8版本,右侧为3.9及以上版本):
在这里插入图片描述“-t general’'表示block type是通用类型,”-l cpp square_ff"表示文件类型为cpp(c++语言,也可采用python设计),block名称为square_ff。
当前可以没有版权指定名(默认为gr-module的作者),这里输入gnuradio.org,也无默认参数default arguments。选择python QA code而不选择C++ QA code,QA程序用作编写block的功能测试。
(2)编写QA测试文件(GR3.9以上版本)
QA文件在gr-howto/python文件夹下,名称为qa_square_ff.py.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright 2021 gnuradio.org.
#
# SPDX-License-Identifier: GPL-3.0-or-later
#from gnuradio import gr, gr_unittest
from gnuradio import blockstry:from howto import square_ff
except ImportError:import osimport sysdirname, filename = os.path.split(os.path.abspath(__file__))sys.path.append(os.path.join(dirname, "bindings"))from howto import square_ffclass qa_square_ff(gr_unittest.TestCase):def setUp(self):self.tb = gr.top_block()def tearDown(self):self.tb = Nonedef test_instance(self):# FIXME: Test will fail until you pass sensible arguments to the constructorinstance = square_ff()def test_001_square_ff(self):      src_data = (-3, 4, -5.5, 2, 3)expected_result = (9, 16, 30.25, 4, 9)src = blocks.vector_source_f(src_data)sqr = square_ff()dst = blocks.vector_sink_f()self.tb.connect(src, sqr)self.tb.connect(sqr,dst)self.tb.run()result_data = dst.data()self.assertFloatTuplesAlmostEqual(expected_result, result_data, 6)# check dataif __name__ == '__main__':gr_unittest.run(qa_square_ff, "qa_square_ff.yaml")

(3) 编写block C++文件
OOT的C++描述文件位于gr-howto/lib文件夹下,名称为square_ff_impl.cc和square_ff_impl.h。其中,.h文件已经生成完备,通常不需要修改。
square_ff_impl.cc修改后完整文件如下:

/* -*- c++ -*- */
/** Copyright 2021 gnuradio.org.** SPDX-License-Identifier: GPL-3.0-or-later*/#include "square_ff_impl.h"
#include <gnuradio/io_signature.h>namespace gr {
namespace howto {using input_type = float;
using output_type = float;
square_ff::sptr square_ff::make() { return gnuradio::make_block_sptr<square_ff_impl>(); }/** The private constructor*/
square_ff_impl::square_ff_impl(): gr::block("square_ff",gr::io_signature::make(1 /* min inputs */, 1 /* max inputs */, sizeof(input_type)),gr::io_signature::make(1 /* min outputs */, 1 /*max outputs */, sizeof(output_type)))
{
}/** Our virtual destructor.*/
square_ff_impl::~square_ff_impl() {}void square_ff_impl::forecast(int noutput_items, gr_vector_int& ninput_items_required)
{/* <+forecast+> e.g. ninput_items_required[0] = noutput_items */ninput_items_required[0] = noutput_items;
}int square_ff_impl::general_work(int noutput_items,gr_vector_int& ninput_items,gr_vector_const_void_star& input_items,gr_vector_void_star& output_items)
{const float *in = (const float *) input_items[0];float *out = (float *) output_items[0];for(int i = 0; i < noutput_items; i++) {out[i] = in[i] * in[i];}// Tell runtime system how many input items we consumed on// each input stream.consume_each (noutput_items);// Tell runtime system how many output items we produced.return noutput_items;
}} /* namespace howto */
} /* namespace gr */

square_ff_impl.h:

/* -*- c++ -*- */
/** Copyright 2021 
gnuradio.org.** SPDX-License-Identifier: GPL-3.0-or-later*/#ifndef INCLUDED_HOWTO_SQUARE_FF_IMPL_H
#define INCLUDED_HOWTO_SQUARE_FF_IMPL_H#include <howto/square_ff.h>namespace gr {
namespace howto {class square_ff_impl : public square_ff
{
private:// Nothing to declare in this block.public:square_ff_impl();~square_ff_impl();// Where all the action really happensvoid forecast(int noutput_items, gr_vector_int& ninput_items_required);int general_work(int noutput_items,gr_vector_int& ninput_items,gr_vector_const_void_star& input_items,gr_vector_void_star& output_items);
};} // namespace howto
} // namespace gr#endif /* INCLUDED_HOWTO_SQUARE_FF_IMPL_H */

(4) 进行编译和测试:gr-howto module文件夹下依次输入如下指令
$mkdir build
$cd build
$cmake . ./
在这里插入图片描述
再执行make:
$make
make完成后即可进行QA测试文件的测试:
$make test
在这里插入图片描述
一切正常,测试成功,如果出现错误,可使用 $ctest -V,查看具体错误报告。
(5)安装module和block至Gnuradio
$ gr_modtool makeyaml square_ff
运行指令,自动更新yml文件,更新后通常还需要一些修改。
在这里插入图片描述
注意:gr_modtool更新生成的yml文件,其中的注释必须要删除!!!
在这里插入图片描述修改后的yaml文件如下:

id: howto_square_ff
label: square_ff
category: '[howto]'
templates:imports: import howtomake: howto.square_ff()
inputs:
- label: indomain: streamdtype: floatmultiplicity: 1 
outputs:
- label: outdomain: streamdtype: floatmultiplicity: 1 
file_format: 1

回到build路径下,进行OOT的安装指令(只有安装后才能在Gnuradio界面显示)
$sudo make install
$sudo ldconfig
安装完后打开Gnuradio界面,可以看到右侧module栏增加了howto,包含block square_ff。
在这里插入图片描述
至此单个block的设计和安装过程结束。

3.在OOT module中继续添加一个模块(名称为square2_ff)

(1)在gr-howto文件夹下执行指令:
$ gr_modtool add square2_ff
该模块与上述的square_ff的模块类型不同,是Sync,即输入输出流数据比例是1:1,也可看做general通用类型的子类,在cpp代码上也有一些区别。
执行步骤同上:
在这里插入图片描述
此次添加的新模块需要执行(修改原block的源码也需要):
$gr_modtool bind square2_ff
在这里插入图片描述
补充:当.cc源文件调用一些malloc等std库时,可能存在版本问题报错,如下:
在这里插入图片描述
Ubuntu21.10下,GNU Radio3.10git 在进行OOT block的绑定时,执行gr_modtool bind …指令,报错如上图:
通过终端命令:python3 -c “import pygccxml; print(pygccxml.version)”
可以看到已经pygccxml的版本为2.2.1(最新版),可通过卸载pygccxml,解决上述问题,运行指令:
$ pip uninstall pygccxml
在这里插入图片描述

再次运行gr_modtool指令,成功bind。

(2) 依次修改文件:qa_square2_ff.py,square2_ff_impl.cc,howto_square2_ff.block.yml,完整代码依次如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright 2021 gnuradio.org.
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
from gnuradio import gr, gr_unittest
from gnuradio import blocks
try:from howto import square2_ff
except ImportError:import osimport sysdirname, filename = os.path.split(os.path.abspath(__file__))sys.path.append(os.path.join(dirname, "bindings"))from howto import square2_ffclass qa_square2_ff(gr_unittest.TestCase):def setUp(self):self.tb = gr.top_block()def tearDown(self):self.tb = Nonedef test_instance(self):# FIXME: Test will fail until you pass sensible arguments to the constructorinstance = square2_ff()def test_001_square2_ff(self):      src_data = (-3, 4, -5.5, 2, 3)expected_result = (9, 16, 30.25, 4, 9)src = blocks.vector_source_f(src_data)sqr = square2_ff()dst = blocks.vector_sink_f()self.tb.connect(src, sqr)self.tb.connect(sqr,dst)self.tb.run()result_data = dst.data()self.assertFloatTuplesAlmostEqual(expected_result, result_data, 6)# check dataif __name__ == '__main__':gr_unittest.run(qa_square2_ff)
/* -*- c++ -*- */
/** Copyright 2021 
gnuradio.org.** SPDX-License-Identifier: GPL-3.0-or-later*/#include "square2_ff_impl.h"
#include <gnuradio/io_signature.h>namespace gr {
namespace howto {using input_type = float;
using output_type = float;
square2_ff::sptr square2_ff::make() { return gnuradio::make_block_sptr<square2_ff_impl>(); }
/** The private constructor*/
square2_ff_impl::square2_ff_impl(): gr::sync_block("square2_ff",gr::io_signature::make(1 /* min inputs */, 1 /* max inputs */, sizeof(input_type)),gr::io_signature::make(1 /* min outputs */, 1 /*max outputs */, sizeof(output_type)))
{
}/** Our virtual destructor.*/
square2_ff_impl::~square2_ff_impl() {}int square2_ff_impl::work(int noutput_items,gr_vector_const_void_star& input_items,gr_vector_void_star& output_items)
{const float *in = (const float *) input_items[0];float *out = (float *) output_items[0];for(int i = 0; i < noutput_items; i++) {out[i] = in[i] * in[i];}return noutput_items;
}} /* namespace howto */
} /* namespace gr */
id: howto_square2_ff
label: square2_ff
category: '[howto]'
templates:imports: import howtomake: howto.square2_ff()
inputs:
- label: indomain: streamdtype: floatmultiplicity: 1 
outputs:
- label: outdomain: streamdtype: floatmultiplicity: 1 
file_format: 1

(3) 进入build文件夹,依次执行命令:
$cmake . ./
$make
执行make过程中就遇到如下错误:
在这里插入图片描述Pydoc.h文件是gr_modtool工具自动产生的,提示#include包含错误,怀疑是square2_ff作为后续block添加,可能与之前已经执行过的make指令冲突,因此想到一种极端方法,清空删除build内的所有文件,再重新执行make的一套指令(因square_ff已经调试确认无误,重新make也不会影响square_ff)。
$cmake . ./
$make
$make test
再次测试,测试通过
在这里插入图片描述
(4) 再进行OOT的安装,因已经修改了yml文件,可以直接执行如下指令:
$sudo make install
$sudo ldconfig
至此完成所有安装工作!!!Gnuradio软件界面可以看到两个block均存在,且可正常使用。
在这里插入图片描述

三、运行测试

流程图及运行结果如下(signal1和2重合,两个block运行结果一致)
在这里插入图片描述

总结

对于OOT模块创建,module下添加单个block很顺利,但添加多个block模块时,按上述方法略为复杂,还需继续根据官方步骤完善。

这篇关于Gnuradio(3.10)创建OOT自定义模块--USRP X410软件无线电平台开发的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/627749

相关文章

流媒体平台/视频监控/安防视频汇聚EasyCVR播放暂停后视频画面黑屏是什么原因?

视频智能分析/视频监控/安防监控综合管理系统EasyCVR视频汇聚融合平台,是TSINGSEE青犀视频垂直深耕音视频流媒体技术、AI智能技术领域的杰出成果。该平台以其强大的视频处理、汇聚与融合能力,在构建全栈视频监控系统中展现出了独特的优势。视频监控管理系统EasyCVR平台内置了强大的视频解码、转码、压缩等技术,能够处理多种视频流格式,并以多种格式(RTMP、RTSP、HTTP-FLV、WebS

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听