综述
本文通过在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-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个文件如下:
1 /* -*- c++ -*- */
2 /*
3 * Copyright 2016 <+YOU OR YOUR COMPANY+>.
4 *
5 * This is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3, or (at your option)
8 * any later version.
9 *
10 * This software is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this software; see the file COPYING. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street,
18 * Boston, MA 02110-1301, USA.
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <gnuradio/io_signature.h>
26 #include "phase_offset_impl.h"
27
28 namespace gr {
29 namespace myblk {
30
31 phase_offset::sptr
32 phase_offset::make(double angle)
33 {
34 return gnuradio::get_initial_sptr
35 (new phase_offset_impl(angle));
36 }
37
38 /*
39 * The private constructor
40 */
41 phase_offset_impl::phase_offset_impl(double angle)
42 : gr::sync_block("phase_offset",
43 gr::io_signature::make(1, 1, sizeof(gr_complex)),
44 gr::io_signature::make(1, 1, sizeof(gr_complex)))
45 , d_offset_angle(angle)
46 {}
47
48 /*
49 * Our virtual destructor.
50 */
51 phase_offset_impl::~phase_offset_impl()
52 {
53 }
54
55 int
56 phase_offset_impl::work(int noutput_items,
57 gr_vector_const_void_star &input_items,
58 gr_vector_void_star &output_items)
59 {
60 const gr_complex *in = (const gr_complex *) input_items[0];
61 gr_complex *out = (gr_complex *) output_items[0];
62
63 double rad = d_offset_angle/180*PI;//将角度变成弧度
64 // Do <+signal processing+>
65 for (int i = 0; i < noutput_items; ++i)
66 {
67 out[i] = in[i] * gr_complex(cos(rad), sin(rad));
68 }
69
70 std::cout << "d_offset_angle = " << d_offset_angle << std::endl;
71
72 // Tell runtime system how many output items we produced.
73 return noutput_items;
74 }
75
76 } /* namespace myblk */
77 } /* namespace gr */
View Code phase_offset_impl.cc
1 /* -*- c++ -*- */
2 /*
3 * Copyright 2016 <+YOU OR YOUR COMPANY+>.
4 *
5 * This is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3, or (at your option)
8 * any later version.
9 *
10 * This software is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this software; see the file COPYING. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street,
18 * Boston, MA 02110-1301, USA.
19 */
20
21 #ifndef INCLUDED_MYBLK_PHASE_OFFSET_IMPL_H
22 #define INCLUDED_MYBLK_PHASE_OFFSET_IMPL_H
23
24 #include <myblk/phase_offset.h>
25
26 namespace gr {
27 namespace myblk {
28
29 class phase_offset_impl : public phase_offset
30 {
31 private:
32 double d_offset_angle;
33
34 public:
35 phase_offset_impl(double angle);
36 ~phase_offset_impl();
37
38 void set_angle_offset(double angle)
39 {
40 d_offset_angle = angle;
41 }
42
43 // Where all the action really happens
44 int work(int noutput_items,
45 gr_vector_const_void_star &input_items,
46 gr_vector_void_star &output_items);
47 };
48
49 } // namespace myblk
50 } // namespace gr
51
52 #endif /* INCLUDED_MYBLK_PHASE_OFFSET_IMPL_H */
View Code phase_offset_impl.h
1 /* -*- c++ -*- */
2 /*
3 * Copyright 2016 <+YOU OR YOUR COMPANY+>.
4 *
5 * This is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3, or (at your option)
8 * any later version.
9 *
10 * This software is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this software; see the file COPYING. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street,
18 * Boston, MA 02110-1301, USA.
19 */
20
21
22 #ifndef INCLUDED_MYBLK_PHASE_OFFSET_H
23 #define INCLUDED_MYBLK_PHASE_OFFSET_H
24
25 #include <myblk/api.h>
26 #include <gnuradio/sync_block.h>
27
28 #define PI 3.14159265358979323846
29
30 namespace gr {
31 namespace myblk {
32
33 /*!
34 * \brief <+description of block+>
35 * \ingroup myblk
36 *
37 */
38 class MYBLK_API phase_offset : virtual public gr::sync_block
39 {
40 public:
41 typedef boost::shared_ptr<phase_offset> sptr;
42
43 /*!
44 * \brief Return a shared_ptr to a new instance of myblk::phase_offset.
45 *
46 * To avoid accidental use of raw pointers, myblk::phase_offset's
47 * constructor is in a private implementation
48 * class. myblk::phase_offset::make is the public interface for
49 * creating new instances.
50 */
51 static sptr make(double angle);
52 virtual void set_angle_offset(double angle) = 0;
53 };
54
55 } // namespace myblk
56 } // namespace gr
57
58 #endif /* INCLUDED_MYBLK_PHASE_OFFSET_H */
View Code phase_offset.h
1 <block>
2 <name>Phase offset</name>
3 <key>myblk_phase_offset</key>
4 <category>MYBLK</category>
5 <import>import myblk</import>
6 <make>myblk.phase_offset($angle)</make>
7 <callback>set_angle_offset($angle)</callback>
8 <param>
9 <name>Angle</name>
10 <key>angle</key>
11 <value>0</value>
12 <type>real</type>
13 </param>
14 <sink>
15 <name>in</name>
16 <type>complex</type>
17 </sink>
18 <source>
19 <name>out</name>
20 <type>complex</type>
21 </source>
22 </block>
View Code 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 即可解决.
6. 在GRC中测试验证
流图与运行结果如下:
注意事项
<callback>...</callback> 关键字,调用C++的成员函数,修改成员变量的值。如本程序中xml中的语句: <callback>set_angle_offset($angle)</callback>
对应C++中函数如下:
1 void set_angle_offset(double angle)
2 {
3 d_offset_angle = angle;
4 }
除此之外,还要注意参数类型匹配。WX GUI Slider传递的参数类型为real,因此angle的数据类型也应该为real,如果设置为int则会报错,grc不会像C++一样支持数据类型隐式转换,因此要注意类型匹配。
Slider中输入的是角度,C++运算时需要将角度转化成弧度来计算。