[GRC] 自定义模块phase_offset

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. 添加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...

3. 编辑代码

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

× lib/phase_offset_impl.h
× lib/phase_offset_impl.cc
× include/myblk/phase_offset.h
× grc/myblk_phase_offset.xml
分别修改这4个文件如下:

lib/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_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 */

lib/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.
 */

#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(1, 1, sizeof(gr_complex)),
              gr::io_signature::make(1, 1, 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[0];
        gr_complex *out = (gr_complex *) output_items[0];

        double rad = d_offset_angle/180*PI;//将角度变成弧度
        // Do <+signal processing+>
        for (int i = 0; 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 */

include/myblk/phase_offset.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 {

    /*!
     * rief <+description of block+>
     * ingroup myblk
     *
     */
    class MYBLK_API phase_offset : virtual public gr::sync_block
    {
     public:
      typedef boost::shared_ptr<phase_offset> sptr;

      /*!
       * rief 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) = 0;
    };

  } // namespace myblk
} // namespace gr

#endif /* INCLUDED_MYBLK_PHASE_OFFSET_H */

grc/myblk_phase_offset.xml

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

4. 编译

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

/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

5. 在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++运算时需要将角度转化成弧度来计算。

原文地址:https://www.cnblogs.com/jsdy/p/13726454.html