• GNU Radio: 自定义 block 实例


    综述

    本文通过在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个文件如下:

     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      * rief <+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        * rief 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 ldconfig 即可解决.

    6. 在GRC中测试验证

      流图与运行结果如下:

          

          

          

    注意事项

      一般我们在block设置的参数,只有在C++类的构造函数中初始化一次赋值。也就是说我们设置的参数只能在程序运行的一开始将参数传递到C++中。但是如果要想像上面的 block 那样在程序运行过程中实时改变参数的值,就需要在xml文件中调用 <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++运算时需要将角度转化成弧度来计算。

  • 相关阅读:
    RuntimeError: cryptography is required for sha256_password or caching_sha2_p
    Django-C003-视图
    MySQL 实时监控日志
    ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061) : 第一次设置MySQL也适用
    Django-C002-深入模型,到底有多深
    ubuntu16.04下安装&配置anaconda+tensorflow新手教程
    人脸算法系列:MTCNN人脸检测详解
    YOLO系列:YOLOv1,YOLOv2,YOLOv3,YOLOv4,YOLOv5简介
    python __getitem__()方法理解
    启动scala的方法
  • 原文地址:https://www.cnblogs.com/moon1992/p/5787164.html
Copyright © 2020-2023  润新知