GNU Radio 学习使用 OOT 系列教程:

GNU Radio3.8创建OOT的详细过程(基础/C++)

GNU Radio3.8创建OOT的详细过程(进阶/C++)

GNU Radio3.8创建OOT的详细过程(python)

GNU Radio自定义模块:Embedded Python Block的使用

GNU Radio3.8:编辑yaml文件的方法

GNU Radio3.8:创建自定义的QPSK块(C++)

----------------------------------------------------------------------------------------

目录

一、sync block 的创建

二、一些其他类型的块

1、Sources 和 Sinks

2、Hierarchical blocks

3、Decimation Block

4、Interpolation Block


在上篇文章《GNU 3.8创建OOT的详细过程(基础/C++) 》我们创建了一个 general 类型的 block ,文章的结尾我们提到,对于输入输出数据比固定为 1:1 的情况下,我们可以对 “general” 类型的 block 的代码进行进行简化,这样就引出了本文要讲的 sync 类型的 block 。

对于输入输出数据比固定为 1:1 时还有一种特殊情况:即我们需要用到 N 个数据来生成一个输出,但是这 N 个数据中前 N-1 个数据为历史记录的数据,只有第 N 个数据为当前的新数据(类似滑动窗口中每滑动一步就会记载一个新的数据并丢掉一个最旧的数据,注意其与插值 1:N 数据比以及抽取操作 N:1 数据比的区别)。对于前 N-1 个数据来说,这在 GR 中是一种叫做 “history” 的概念,这时就需要在构造函数中或在需求发生变化时调用 set_history()。例如,对于非抽取、非插值的 FIR 滤波器来说,需要检查它产生的每个输出样本的 N 个输入样本,其中 N 是滤波器中的抽头数。但是,它每次只消耗1个输入样本来产生1个输出。

官方对 generalsync 的解释为:

General This block a generic version of all blocks
Sync The sync block allows users to write blocks that consume and produce an equal number of items per port. From the user perspective, the GNU Radio scheduler synchronizes the input and output items, it has nothing to with synchronization algorithms

一、sync block 的创建

sync block 的创建过程与 general block 的创建方法类似。我们还在 之前创建的 mymod 模块 的基础上 添加一个名为 square2_ff 的 sync block,作用与之前的 square1_ff 一样。命令为:gr_modtool add -t sync -l cpp square2_ff

wsx@wsx:~/temp/gr-mymod$ gr_modtool add -t sync -l cpp square2_ff
GNU Radio module name identified: mymod
Language: C++
Block/code identifier: square2_ff
Please specify the copyright holder:
Enter valid argument list, including default arguments:
Add Python QA code? [Y/n] y
Add C++ QA code? [y/N] n
Adding file 'lib/square2_ff_impl.h'...
Adding file 'lib/square2_ff_impl.cc'...
Adding file 'include/mymod/square2_ff.h'...
Editing swig/mymod_swig.i...
Adding file 'python/qa_square2_ff.py'...
Editing python/CMakeLists.txt...
Adding file 'grc/mymod_square2_ff.block.yml'...
Editing grc/CMakeLists.txt...

同样的,仍然使用 python 测试文件,命令参数及最终生成的文件等内容在 上一篇文章 中已详细介绍,这里就不在赘述啦~

下面是测试代码 python/qa_square2_ff.py 的编写:

# python/qa_square2_ff.py
from gnuradio import gr, gr_unittest
from gnuradio import blocks
import mymod_swig as mymodclass qa_square2_ff(gr_unittest.TestCase):def setUp(self):self.tb = gr.top_block()def tearDown(self):self.tb = Nonedef 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 = mymod.square2_ff()dst = blocks.vector_sink_f()self.tb.connect(src, 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)

然后是 lib/square2_ff_impl.cc 代码的填写:

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif#include <gnuradio/io_signature.h>
#include "square2_ff_impl.h"namespace gr {namespace mymod {square2_ff::sptrsquare2_ff::make(){return gnuradio::get_initial_sptr(new square2_ff_impl());}/* 构造函数 */square2_ff_impl::square2_ff_impl(): gr::sync_block("square2_ff",gr::io_signature::make(1, 1, sizeof (float)), // input signaturegr::io_signature::make(1, 1, sizeof (float))) // output signature{}/* 析构函数 */square2_ff_impl::~square2_ff_impl(){ }// work()是执行实际信号处理任务的函数intsquare2_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];}// Tell runtime system how many output items we produced.return noutput_items;}} /* namespace mymod */
} /* namespace gr */

上述代码中,测试文件的编写没啥区别,区别主要是在 square2_ff_impl.cc 代码中。可以发现,新的代码中的代码量少了不少,信号处理主函数由 work()取代了 general_work() ,并且省略了 ninput_items 参数,同时 consume_each() 以及 forecast() 函数也不见了。如果 block 需要大于 1 个 history,则需要在构造函数中或在需求发生变化时调用 set_history()。

这里 forecast 函数虽然没显式调用,但在代码中会隐式实现,系统会默认为1:1的关系。consume_each 函数也是如此。

之后对 square2_ff 进行编译安装。由于之前添加 square2_ff 时 gr_modtool 已自动修改 CMakeList 文件,这里在 build/ 文件夹中可以直接 make,系统会自动重新 cmake 然后再make:

wsx@wsx:~/temp/gr-mymod/build$ make -j10
-- Build type not specified: defaulting to release.
-- Using GMP.
-- User set python executable /usr/bin/python3
-- Found PythonLibs: /usr/lib/x86_64-linux-gnu/libpython3.8.so (found suitable exact version "3.8.10")
-- Using install prefix: /usr/local
-- Building for version: v1.0-compat-xxx-xunknown / 1.0.0git
-- No C++ unit tests... skipping
--
-- Checking for module SWIG
-- Found SWIG version 4.0.1.
-- Found PythonLibs: /usr/lib/x86_64-linux-gnu/libpython3.8.so (found version "3.8.10")
-- Configuring done
-- Generating done
-- Build files have been written to: /home/wsx/temp/gr-mymod/build
[ 20%] Built target pygen_apps_9a6dd
[ 33%] Built target doxygen_target
[ 33%] Built target _mymod_swig_doc_tag
[ 33%] Built target pygen_python_6451a
Scanning dependencies of target gnuradio-mymod
[ 46%] Built target mymod_swig_swig_doc
Scanning dependencies of target mymod_swig_swig_compilation
[ 60%] Building CXX object lib/CMakeFiles/gnuradio-mymod.dir/square2_ff_impl.cc.o
[ 60%] Swig source mymod_swig.i
[ 60%] Built target mymod_swig_swig_compilation
[ 66%] Linking CXX shared library libgnuradio-mymod.so
[ 73%] Built target gnuradio-mymod
Scanning dependencies of target mymod_swig
[ 80%] Building CXX object swig/CMakeFiles/mymod_swig.dir/CMakeFiles/mymod_swig.dir/mymod_swigPYTHON_wrap.cxx.o
[ 86%] Linking CXX shared module _mymod_swig.so
[ 86%] Built target mymod_swig
[100%] Generating mymod_swig.pyo
[100%] Generating mymod_swig.pyc
[100%] Built target pygen_swig_1e481

之后又是 make test 。。。emmmmm,你可以先 make test 一下试试,如果能通过,当我下面的 BUG 部分啥也没说哈——如果没通过,而且运行 ctest -V -R square 报错的话,那就继续看下面这部分:

============================== BUG ===============================

报错大概是这样的:ImportError: ×××: undefined symbol ×××

ImportError: /path/to/build/swig/_mymod_swig.so: undefined symbol: _ZN2gr5mymod10square2_ff4makeEv

这就遇到一个很神奇的现象,但是并不影响最终的使用,情况是这样的:

情况1:在本例中,我们是继续 这篇文章 的步骤,在 mymod 模块中添加了第二个 block:square2_ff,这时的情况就是之前那个 block:square1_ff 已经编译过一次,我们是在这样一个基础上再对又添加一个 block 后的两个 block 进行编译。这种情况下,在我进行编译测试的过程中,如果 make 之后紧接着就是 make test 的话,就会出现上面提到的这个问题,这时我找遍了 google 的资源,找到了几个遇到过相似问题的解决方法:

python - gnuradio `ImportError undefined symbol` - Stack Overflow

FAQ - GNU Radio

但是,这种解决方式大致的意思就是说cmakelist文件中没有加入跟 square2_ff 有关的库并需要我们手动加入,emmmmm我照做了,但是没啥用(好吧,我承认是我没太看懂这上面大佬的解决方法说的是个啥。。。),但是直觉告诉我 test 没通过可能也不影响后面的使用,之后我就没管这个这个 test 的问题直接进行 gr_modtool makeyaml square2_ff,然后 sudo make install,然后!我发现 test 没通过确实对结果没影响,square1_ff 和 square2_ff 都能在GRC中使用了!后来在回到 build 文件中运行 make test ,它通过了。。。OK,完成,总结就是:

最好在 sudo make install 之后在运行 make test 。

情况2:在情况1的基础上,我猜测可能是先对 square1_ff 进行编译 的结果影响了后面再加入 的 square2_ff ,因此就尝试删了之前安装好的 block 及 mymod 工程,重新建一个一模一样的,依次完成加入square1_ff / square2_ff 和 相应的 python test 文件等步骤,然后一起一次性完成编译,这时我在 make 命令之后紧接着运行 make test 指令,他真的通过了!

wsx@wsx:~/temp/gr-mymod/build$ make -j10
Scanning dependencies of target pygen_python_6451a
Scanning dependencies of target pygen_apps_9a6dd
Scanning dependencies of target doxygen_target
Scanning dependencies of target _mymod_swig_doc_tag
Scanning dependencies of target gnuradio-mymod
[ 13%] Built target pygen_apps_9a6dd
[ 20%] Generating documentation with doxygen
[ 20%] Generating __init__.pyc
[ 20%] Generating __init__.pyo
[ 26%] Building CXX object swig/CMakeFiles/_mymod_swig_doc_tag.dir/_mymod_swig_doc_tag.cpp.o
[ 33%] Building CXX object lib/CMakeFiles/gnuradio-mymod.dir/square2_ff_impl.cc.o
[ 40%] Building CXX object lib/CMakeFiles/gnuradio-mymod.dir/square1_ff_impl.cc.o
warning: Tag 'PERL_PATH' at line 1686 of file '/home/wsx/temp/gr-mymod/build/docs/doxygen/Doxyfile' has become obsolete.To avoid this warning please remove this line from your configuration file or upgrade it using "doxygen -u"
warning: Tag 'MSCGEN_PATH' at line 1707 of file '/home/wsx/temp/gr-mymod/build/docs/doxygen/Doxyfile' has become obsolete.To avoid this warning please remove this line from your configuration file or upgrade it using "doxygen -u"
[ 40%] Built target pygen_python_6451a
[ 40%] Built target doxygen_target
[ 46%] Linking CXX executable _mymod_swig_doc_tag
[ 46%] Built target _mymod_swig_doc_tag
Scanning dependencies of target mymod_swig_swig_doc
[ 53%] Generating doxygen xml for mymod_swig_doc docs
warning: Tag 'PERL_PATH' at line 1654 of file '/home/wsx/temp/gr-mymod/build/swig/mymod_swig_doc_swig_docs/Doxyfile' has become obsolete.To avoid this warning please remove this line from your configuration file or upgrade it using "doxygen -u"
warning: Tag 'MSCGEN_PATH' at line 1675 of file '/home/wsx/temp/gr-mymod/build/swig/mymod_swig_doc_swig_docs/Doxyfile' has become obsolete.To avoid this warning please remove this line from your configuration file or upgrade it using "doxygen -u"
[ 60%] Generating python docstrings for mymod_swig_doc
[ 60%] Built target mymod_swig_swig_doc
Scanning dependencies of target mymod_swig_swig_compilation
[ 66%] Swig source mymod_swig.i
[ 66%] Built target mymod_swig_swig_compilation
[ 73%] Linking CXX shared library libgnuradio-mymod.so
[ 73%] Built target gnuradio-mymod
Scanning dependencies of target mymod_swig
[ 80%] Building CXX object swig/CMakeFiles/mymod_swig.dir/CMakeFiles/mymod_swig.dir/mymod_swigPYTHON_wrap.cxx.o
[ 86%] Linking CXX shared module _mymod_swig.so
[ 86%] Built target mymod_swig
Scanning dependencies of target pygen_swig_1e481
[100%] Generating mymod_swig.pyo
[100%] Generating mymod_swig.pyc
[100%] Built target pygen_swig_1e481
wsx@wsx:~/temp/gr-mymod/build$ make test
Running tests...
Test project /home/wsx/temp/gr-mymod/buildStart 1: qa_square1_ff
1/2 Test #1: qa_square1_ff ....................   Passed   17.04 secStart 2: qa_square2_ff
2/2 Test #2: qa_square2_ff ....................   Passed    0.73 sec100% tests passed, 0 tests failed out of 2Total Test time (real) =  18.10 sec

情况就是这么个情况,玄乎。。好了,问题解决了,我们继续讲后面的

============================== END ===============================

下面是安装完成之后的效果:

运行的结果如下:

二、一些其他类型的块

1、Sources 和 Sinks

Sources 和 Sinks 都是 gr:sync_block 的派生类。唯一不同的是 sources 没有输入端口。sinks没有输出端口,这些由 gr::io_signature::make 控制。可以在源码文件中查看一些例子:

gr-blocks / lib / file_source_impl.cc、file_source.{h,cc}、file_sink_impl.{h,cc}

2、Hierarchical blocks

Hierarchical(分层) blocks 是由其他 blocks 组成的一种 block,它可以实例化其他 blocks 或者 hierarchical blocks 并将他们连接起来,为了达到这个目的,hierarchical block 内部有一个“connect” 函数可供调用。hierarchical block 可以像普通 block 一样定义输入输出流。

把一个输入 i 连接到一个 hierarchical block 的python 代码:

self.connect((self, <i>), <block>)

类似地,要将信号从输出流 o 上的块发送出去的代码:

self.connect(<block>, (self, <o>))

与创建 sync 及 general 的方法一样,使用 gr_modtool 创建 hierarchical block 的命令如下:

gr_modtool.py add -t hier -l cpp hierblockcpp_ff

3、Decimation Block

decimation(抽取) block 是另一种类型的固定速率块(N : 1),其中输入项的数量是输出项数量的固定倍数。一个  decimation block 的 C++ 例子如下:

#include <gr_sync_decimator.h>class my_decim_block : public gr_sync_decimator
{
public:my_decim_block(...):gr_sync_decimator("my decim block", in_sig,out_sig,decimation){//constructor stuff}//work function here...
};

gr_sync_decimator 构造函数的第四个参数 decimation 为抽取因子。另外,不难理解,输入项目的数量 = noutput_items * decimation

4、Interpolation Block

与decimation block 作用相反,interpolation(插值) block 是另一种固定速率块(1 : N),其中输出项的数量是输入项数量的固定倍数。C++例子如下。

#include <gr_sync_interpolator.h>class my_interp_block : public gr_sync_interpolator
{
public:my_interp_block(...):gr_sync_interpolator("my interp block", in_sig,out_sig,interpolation){//constructor stuff}//work function here...
};

参考网站:

OutOfTreeModules - GNU Radio

BlocksCodingGuide - GNU Radio

GNU Radio Manual and C++ API Reference: gr::block Class Reference

GNU Radio3.8创建OOT的详细过程(进阶/C++)相关推荐

  1. GNU Radio3.8创建OOT的详细过程(基础/C++)

    GNU Radio 学习使用 OOT 系列教程: GNU Radio3.8创建OOT的详细过程(基础/C++) GNU Radio3.8创建OOT的详细过程(进阶/C++) GNU Radio3.8创 ...

  2. GNU Radio3.8创建OOT的详细过程(python)

    GNU Radio 学习使用 OOT 系列教程: GNU Radio3.8创建OOT的详细过程(基础/C++) GNU Radio3.8创建OOT的详细过程(进阶/C++) GNU Radio3.8创 ...

  3. GNU Radio3.8:创建自定义的QPSK块(C++)

    GNU Radio 学习使用 OOT 系列教程: GNU Radio3.8创建OOT的详细过程(基础/C++) GNU Radio3.8创建OOT的详细过程(进阶/C++) GNU Radio3.8创 ...

  4. 最适合新手看的平衡二叉搜索树(BBST)的创建,包含详细过程,一看就会(C++版)

    写在前面:本人大二小白,本篇文章是我第一次写博客,用来记录我的学习过程,我想将我在学习中遇到的各种的问题和困难写下来,希望大家能够不要犯同样的错误.我会尽可能的详细的把每一个步骤都解释清楚,那么废话不 ...

  5. socket:内核初始化及创建流(文件)详细过程

    socket中文名称为套接字,属于传输协议及功能接口的封装.socket首先初始化注册(socket)文件系统,然后由使用它的模块传入具体的地址族(类型)family,如ipv4模块中的(void)s ...

  6. MySQL中关于临时表的创建到删除详细过程

    1.临时表的创建: CREATE TEMPORARY TABLE SalesSummary (product_name VARCHAR(50) NOT NULL, total_sales DECIMA ...

  7. Oracle 创建表空间详细过程

    此空间是用来进行数据存储的(表.function.存储过程等),所以是实际物理存储区域. 主要用途是在数据库进行排序运算[如创建索引.order by及group by.distinct.union/ ...

  8. Hive创建表的过程详细过程

    Hive创建表的过程详细过程 Demo 第一个demo CREATE TABLE db.testTable(id string COMMENT 'id',name string COMMENT '姓名 ...

  9. 菜鸟教程 | IDEA创建一个spring boot项目的详细过程

    目录 1.新建项目 2.选择项目所需依赖 3.手动导入部分依赖 创建spring项目的详细过程~ 1.新建项目 file --> new -->  project groupid 和 ar ...

最新文章

  1. 前端自动化构建工具webpack (二)之css和插件加载总结
  2. mustache 渲染文本一直渲染不出来
  3. jmeter 导入java_8. Jmeter导入jar包
  4. C语言实现PID算法:位置式PID和增量式PID
  5. Android JNI 使用的数据结构JNINativeMethod详解
  6. DNS扫盲系列之五:域名配置ZONE文件
  7. 笔记-高项案例题-2009年上-需求管理
  8. Python 3 集合基础和概念!
  9. 【渝粤教育】广东开放大学 性考 形成性考核 (33)
  10. Flash基本概念和原理
  11. chromium关闭更新_你的Win10系统20H2了吗此乃Win10年度最靠谱的更新还有Win10优化大师助阵...
  12. 重装64位WIN7之后再装KUBUNTU遇到的问题
  13. swagger 返回json字符串_[Swagger] Swagger Codegen 高效开发客户端对接服务端代码
  14. ant基本命令和使用
  15. IOS改地区:美国、新西兰等等
  16. mysql支付成功订单数超过10_1.超时未支付订单处理
  17. 测试cpu单核分数软件,最新geekbench5 CPU跑分天梯排行榜
  18. Termux安装数据库(手机安装数据库)...
  19. FPGA之4K图像处理
  20. 营业日志 2020.5.20

热门文章

  1. TensorRT ONNX 基础
  2. #VirtualBox# 修改虚拟磁盘大小
  3. ios 点生成线路 百度地图_百度地图下载-百度地图ios版15.3.0苹果版-东坡下载
  4. FPGA——用VGA时序显示图像(3)(代码)
  5. python pip 手动安装
  6. 招聘 | 蚂蚁集团-NLP-大模型/深度学习/数字人算法-3个岗位-社招
  7. 西蒙·威利森的博客对博客的建议
  8. 【状态】:今日踽踽独行,他日化蝶归去
  9. scl语言用plc脉冲做定时器_西门子PLC中使用SCL语言编程的技巧
  10. Python常用内置类和常用内置函数汇总