IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> GNU 3.8创建OOT的详细过程(进阶/C++) -> 正文阅读

[C++知识库]GNU 3.8创建OOT的详细过程(进阶/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 的解释为:

GeneralThis block a generic version of all blocks
SyncThe 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 mymod

class qa_square2_ff(gr_unittest.TestCase):

    def setUp(self):
        self.tb = gr.top_block()

    def tearDown(self):
        self.tb = None

    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 = 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 data

if __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::sptr
    square2_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 signature
                  gr::io_signature::make(1, 1, sizeof (float))) // output signature
    {}

    /* 析构函数 */
    square2_ff_impl::~square2_ff_impl()
    { }

    // work()是执行实际信号处理任务的函数
    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];
      }

      // 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 的资源,找到了几个遇到过相似问题的解决方法:

https://stackoverflow.com/questions/28859517/gnuradio-importerror-undefined-symbol

https://wiki.gnuradio.org/index.php/FAQ#In_my_OOT_Module.2C_I.27m_trying_to_use_a_GNU_Radio_block_or_class_but_get_an_ImportError_.22undefined_symbol.22._What_do_I_do.3F

但是,这种解决方式大致的意思就是说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/build
    Start 1: qa_square1_ff
1/2 Test #1: qa_square1_ff ....................   Passed   17.04 sec
    Start 2: qa_square2_ff
2/2 Test #2: qa_square2_ff ....................   Passed    0.73 sec

100% tests passed, 0 tests failed out of 2

Total 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...
};

参考网站:

https://wiki.gnuradio.org/index.php/OutOfTreeModules

https://wiki.gnuradio.org/index.php/BlocksCodingGuide

https://www.gnuradio.org/doc/doxygen/classgr_1_1block.html

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-13 17:16:52  更:2021-07-13 17:17:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/27 23:00:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码