综述

本文通过在GNU Radio 中编写一个block的例子,系统介绍创建一个block的过程。该 block 的功能是可以在GRC中通过滑块(WX GUI Slider)来实时改变信号源(Signal Source)的相位偏移。

步骤详解

1. 使用 gr_modtool 工具创建 block 的框架,GNU Radio 会自动帮我们创建所需要的文件及文件夹。

$ gr_modtool newmod myblk
Creating out-of-tree module in ./gr-myblk... Done.
Use 'gr_modtool add' to add a new block to this currently empty module.
$ cd gr-myblk
/gr-myblk$ ls
apps cmake CMakeLists.txt docs examples grc include lib python swig

2. 使用Git版本控制(可选)

  在gr-myblock文件夹下执行以下命令,创建一个Git仓库,可用于版本控制。git常用命令速查点这里

/gr-myblk$ git init

3. 添加block

  执行以下命令添加block。参数类型为double,因为我们要传递的角度是0~360度double类型,不填默认没有参数,但后期可以自己添加。根据是否需要Python或者C++测试代码选择Y或者n,如果不填默认为Y。

/gr-myblk$ gr_modtool add -t sync phase_offset
GNU Radio module name identified: myblk
Language: C++
Block/code identifier: phase_offset
Enter valid argument list, including default arguments: double angle
Add Python QA code? [Y/n] n
Add C++ QA code? [Y/n] n
Adding file 'lib/phase_offset_impl.h'...
Adding file 'lib/phase_offset_impl.cc'...
Adding file 'include/myblk/phase_offset.h'...
Editing swig/myblk_swig.i...
Adding file 'grc/myblk_phase_offset.xml'...
Editing grc/CMakeLists.txt...

4. 编辑代码

  从上一条命令的输出可以看出,gr_modtood已经为我们自动创建了4个文件,分别是:

  • lib/phase_offset_impl.h
  • lib/phase_offset_impl.cc
  • include/myblk/phase_offset.h
  • grc/myblk_phase_offset.xml

分别修改这4个文件如下:

 /* -*- c++ -*- */
/*
* Copyright 2016 <+YOU OR YOUR COMPANY+>.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/ #ifdef HAVE_CONFIG_H
#include "config.h"
#endif #include <gnuradio/io_signature.h>
#include "phase_offset_impl.h" namespace gr {
namespace myblk { phase_offset::sptr
phase_offset::make(double angle)
{
return gnuradio::get_initial_sptr
(new phase_offset_impl(angle));
} /*
* The private constructor
*/
phase_offset_impl::phase_offset_impl(double angle)
: gr::sync_block("phase_offset",
gr::io_signature::make(, , sizeof(gr_complex)),
gr::io_signature::make(, , sizeof(gr_complex)))
, d_offset_angle(angle)
{} /*
* Our virtual destructor.
*/
phase_offset_impl::~phase_offset_impl()
{
} int
phase_offset_impl::work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
const gr_complex *in = (const gr_complex *) input_items[];
gr_complex *out = (gr_complex *) output_items[]; double rad = d_offset_angle/*PI;//将角度变成弧度
// Do <+signal processing+>
for (int i = ; i < noutput_items; ++i)
{
out[i] = in[i] * gr_complex(cos(rad), sin(rad));
} std::cout << "d_offset_angle = " << d_offset_angle << std::endl; // Tell runtime system how many output items we produced.
return noutput_items;
} } /* namespace myblk */
} /* namespace gr */

phase_offset_impl.cc

 /* -*- c++ -*- */
/*
* Copyright 2016 <+YOU OR YOUR COMPANY+>.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/ #ifndef INCLUDED_MYBLK_PHASE_OFFSET_IMPL_H
#define INCLUDED_MYBLK_PHASE_OFFSET_IMPL_H #include <myblk/phase_offset.h> namespace gr {
namespace myblk { class phase_offset_impl : public phase_offset
{
private:
double d_offset_angle; public:
phase_offset_impl(double angle);
~phase_offset_impl(); void set_angle_offset(double angle)
{
d_offset_angle = angle;
} // Where all the action really happens
int work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
}; } // namespace myblk
} // namespace gr #endif /* INCLUDED_MYBLK_PHASE_OFFSET_IMPL_H */

phase_offset_impl.h

 /* -*- c++ -*- */
/*
* Copyright 2016 <+YOU OR YOUR COMPANY+>.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/ #ifndef INCLUDED_MYBLK_PHASE_OFFSET_H
#define INCLUDED_MYBLK_PHASE_OFFSET_H #include <myblk/api.h>
#include <gnuradio/sync_block.h> #define PI 3.14159265358979323846 namespace gr {
namespace myblk { /*!
* \brief <+description of block+>
* \ingroup myblk
*
*/
class MYBLK_API phase_offset : virtual public gr::sync_block
{
public:
typedef boost::shared_ptr<phase_offset> sptr; /*!
* \brief Return a shared_ptr to a new instance of myblk::phase_offset.
*
* To avoid accidental use of raw pointers, myblk::phase_offset's
* constructor is in a private implementation
* class. myblk::phase_offset::make is the public interface for
* creating new instances.
*/
static sptr make(double angle);
virtual void set_angle_offset(double angle) = ;
}; } // namespace myblk
} // namespace gr #endif /* INCLUDED_MYBLK_PHASE_OFFSET_H */

phase_offset.h

 <block>
<name>Phase offset</name>
<key>myblk_phase_offset</key>
<category>MYBLK</category>
<import>import myblk</import>
<make>myblk.phase_offset($angle)</make>
<callback>set_angle_offset($angle)</callback>
<param>
<name>Angle</name>
<key>angle</key>
<value>0</value>
<type>real</type>
</param>
<sink>
<name>in</name>
<type>complex</type>
</sink>
<source>
<name>out</name>
<type>complex</type>
</source>
</block>

myblk_phase_offset.xml

5. 编译

  依次执行下面的命令完成编译工作

/gr-myblk$ mkdir build
/gr-myblk$ cd build
/gr-myblk/build$ cmake ../
/gr-myblk/build$ make
/gr-myblk/build$ sudo make install
/gr-myblk/build$ sudo ldconfig

注意:如果出现类似错误提示 AttributeError: 'module' object has no attribute 'xxxx', 运行 sudo ldconfig 即可解决.

6. 在GRC中测试验证

  流图与运行结果如下:

      

      

      

注意事项

  一般我们在block设置的参数,只有在C++类的构造函数中初始化一次赋值。也就是说我们设置的参数只能在程序运行的一开始将参数传递到C++中。但是如果要想像上面的 block 那样在程序运行过程中实时改变参数的值,就需要在xml文件中调用 <callback>...</callback> 关键字,调用C++的成员函数,修改成员变量的值。如本程序中xml中的语句: <callback>set_angle_offset($angle)</callback>

  对应C++中函数如下:

 void set_angle_offset(double angle)
{
d_offset_angle = angle;
}

  除此之外,还要注意参数类型匹配。WX GUI Slider传递的参数类型为real,因此angle的数据类型也应该为real,如果设置为int则会报错,grc不会像C++一样支持数据类型隐式转换,因此要注意类型匹配。

  Slider中输入的是角度,C++运算时需要将角度转化成弧度来计算。

GNU Radio: 自定义 block 实例的更多相关文章

  1. GNU Radio: Synchronization and MIMO Capability with USRP Devices

    Application Note Synchronization and MIMO Capability with USRP Devices Ettus Research Introduction S ...

  2. 【译】GNU Radio How to write a block 【如何开发用户模块及编写功能块】

    本文讲解如何在GNU Radio中添加用户开发的信号处理模块,译文如有不当之处可参考原文地址:http://gnuradio.microembedded.com/outoftreemodules Ou ...

  3. GNU Radio: USRP2 and N2x0 Series

    Comparative features list 相对性能清单 Hardware Capabilities: 1 transceiver card slot External PPS referen ...

  4. GNU Radio 入门培训

    1. GNU Radio介绍 1.1 什么是GNU Radio GNU Radio是一个完全开源的软件无线电结构平台,它可以用来设计和仿真,也可以用来连接真实的无线电系统.GNU Radio是一个高度 ...

  5. GNU Radio: Overview of the GNU Radio Scheduler

    Scetion 1: The Flowgraph The flowgraph moves data from sources into sinks. 一个流图由多个模块组成,其中一般包括信源(Sour ...

  6. GNU Radio: Multiple USRP configurations 配置多个USRP设备

    Introduction 引言 Some USRP devices are capable of being grouped to form a single, virtual device. A s ...

  7. GNU Radio安装教程: Ubuntu14.04 + uhd3.10.0 + gnuradio3.7.10.1

    1. 更新和安装依赖项 在编译安装uhd和gnuradio之前,确保已安装所需依赖项.Ubuntu系统运行: sudo apt-get update 安装UHD和GNURadio所需依赖项: On U ...

  8. GNU Radio Radar Toolbox

    GNU Radio Radar Toolbox Install guide Change to any folder in your home directory and enter followin ...

  9. Objective-C:自定义Block函数

    Block函数是一种类似于函数指针的函数,程序员只需要把需要操作的代码封装到定义的block中即可,以后需要使用时,直接调用,非常方便.... 举例如下: 第一种形式:自定义一个无返回值而且无参数的b ...

随机推荐

  1. 【Error】IOError: [Errno 22] invalid mode ('wb') or filename

    错误描述: IOError: [Errno 22] invalid mode ('wb') or filename: 'C:\\Users\\Viral Patel\\Documents\\GitHu ...

  2. Shell test 命令,Shell 输入/输出重定向

    一.Shell test 命令 Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值.字符和文件三个方面的测试. 数值测试 参数 说明 -eq 等于则为真 -ne 不等于则为真 -g ...

  3. BZOJ2259 [Oibh]新型计算机

    话说hzwer你在坑爹?... 我按照你的建图交了上去,发现WA. 开始检查= =...过了好久,突然觉得画风不对...hzwer您建图错了啊!!! 后来看了看zky的终于知道了怎么回事>_&l ...

  4. LeetCode OJ:Generate Parentheses(括号生成)

    Given n pairs of parentheses, write a function to generate all combinations of well-formed parenthes ...

  5. Python的集合框架

    Python内置了四种集合框架(list.tuple.dict.set) list:list是一种有序的集合 list里面的元素的数据类型也可以不同,list元素也可以是另一个list In [28] ...

  6. 转:JAVA CAS原理深度分析

    看了一堆文章,终于把Java CAS的原理深入分析清楚了. 感谢GOOGLE强大的搜索,借此挖苦下百度,依靠百度什么都学习不到! 参考文档: http://www.blogjava.net/xylz/ ...

  7. Python中方法的缺省参数问题分析

    引言: 在Python中可以缺省给方法制定缺省值,但是这个缺省值在某些情况下确是和我们预期不太一致的-... 这个诡异的问题,曾经困然了我几天时间,才最终定位出来-.. 测试代码 from datet ...

  8. 1. Java EE简介 - JavaEE基础系列

    什么是Java EE? 真的是你理解的那样吗? Java EE, 原名J2EE, 其核心由一系列抽象的标准规范所组成, 是针对目前软件开发中所普遍面临问题的解决方案. 注意以上定义中的"抽象 ...

  9. python数据取整

    第三方包:numpy 安装 $ sudo dnf install numpy 4舍6入5取偶 def getInteger(): a = np.float(5.5) # 4舍6入 5取偶 int_a ...

  10. Android中的按键顺序打乱

    首先要找到相对应的控件,之后再来一个数组,再把数组里面的数字显示到控件上面. private void initView() { mNum0 = (Button) findViewById(R.id. ...