【问题标题】:GNU Radio: How to define a "get_*" method inside a sink blockGNU Radio:如何在 sink 块中定义“get_*”方法
【发布时间】:2016-02-27 02:43:20
【问题描述】:

我想用 1 个输入端口和 0 个输出端口为 C++ 中的 GNU Radio 编写自己的接收器块。我阅读并遵循了此处描述的步骤:

我正在使用

  • Ubuntu 14.04.3 LTS
  • Eclipse 4.5.1
  • CDT 8.8.0.201509131935
  • GNU Radio 3.7.8

我使用 gr_modtool 创建了新模块“jammertrap”。在其中,我创建了“bandpower”块。这其中创建了三个文件

  • /home/sdr/gnuradio/gr-jammertrap/include/jammertrap/ 内的bandpower.h
  • bandpower_impl.h 在 /home/sdr/gnuradio/gr-jammertrap/lib/ 内
  • /home/sdr/gnuradio/gr-jammertrap/lib/ 内的bandpower_impl.cc

bandpower.h:

#ifndef INCLUDED_JAMMERTRAP_BANDPOWER_H
#define INCLUDED_JAMMERTRAP_BANDPOWER_H

#include <jammertrap/api.h>
#include <gnuradio/block.h>

namespace gr
{
    namespace jammertrap
    {
        class JAMMERTRAP_API bandpower : virtual public gr::block
        {
            public:
                typedef boost::shared_ptr<bandpower> sptr;

                // Return a shared_ptr to a new instance of jammertrap::bandpower.
                // To avoid accidental use of raw pointers, jammertrap::bandpower's constructor is in a private implementation class.
                // jammertrap::bandpower::make is the public interface for creating new instances.
                static sptr make();
        };
    } // namespace jammertrap
} // namespace gr

#endif /* INCLUDED_JAMMERTRAP_BANDPOWER_H */

bandpower_impl.h:

#ifndef INCLUDED_JAMMERTRAP_BANDPOWER_IMPL_H
#define INCLUDED_JAMMERTRAP_BANDPOWER_IMPL_H

#include <jammertrap/bandpower.h>

namespace gr
{
    namespace jammertrap
    {
        class bandpower_impl : public bandpower
        {
            private:
                double d_bandpower_;

            public:
                bandpower_impl();
                ~bandpower_impl();

                void forecast (int noutput_items, gr_vector_int &ninput_items_required);

                // Where all the action really happens
                int general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items);

                // Returns the calculated RMS Bandpower
                double get_bandpower();
        };

    } // namespace jammertrap
} // namespace gr

#endif /* INCLUDED_JAMMERTRAP_BANDPOWER_IMPL_H */

bandpower_impl.cc:

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gnuradio/io_signature.h>
#include "bandpower_impl.h"

namespace gr
{
    namespace jammertrap
    {
        bandpower::sptr
        bandpower::make()
        {
            return gnuradio::get_initial_sptr (new bandpower_impl());
        }

        // The private constructor
        bandpower_impl::bandpower_impl() : gr::block("bandpower", gr::io_signature::make(1, 1, sizeof(gr_complex)), gr::io_signature::make(0, 0, 0))
        {
            d_bandpower_ = 0;
        }

        // Our virtual destructor
        bandpower_impl::~bandpower_impl()
        {}

        void bandpower_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required)
        {
            // ninput_items_required[0] = noutput_items;
        }

        int bandpower_impl::general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items)
        {
            const gr_complex *in = (const gr_complex *) input_items[0];

            d_bandpower_ = 0;

            for(int i = 0; i < noutput_items; i++)
            {
                d_bandpower_ += (in[i].real() * in[i].real()) + (in[i].imag() * in[i].imag());
            }
            d_bandpower_ = sqrt(d_bandpower_ / noutput_items);

            // Tell runtime system how many input items we consumed on each input stream.
            consume_each (noutput_items);

            // Tell runtime system how many output items we produced
            return noutput_items;
        }

        double bandpower_impl::get_bandpower()
        {
            return d_bandpower_;
        }
    } /* namespace jammertrap */
} /* namespace gr */

为了制作和安装这个新块,我在 /home/sdr/gnuradio/gr-jammertrap/build 中输入了以下命令:

  • cmake ../
  • 制作
  • make test // 结果:“test_jammertrap”和“qa_bandpower”成功通过
  • sudo make install

这个 sink 块“bandpower”应该接收 gr_complex 类型的项目,计算平均接收功率并将这个值存储在私有成员“d_bandpower_”中。 另外我定义了方法“get_bandpower()”来获取存储的值。

在另一个程序中,我用两个块创建了一个流程图类

osmosdr::source:sptr osmosdr_source_;
gr::jammertrap::bandpower::sptr bandpower_measurement_;

并用实例化它们

osmosdr_source_ = osmosdr::source::make(std::string());
bandpower_measurement_ = gr::jammertrap::bandpower::make();

启动流程图后,我想通过调用 get_bandpower() 来读取计算的带宽,但 Eclipse 没有显示方法“bandpower_measurement_->get_bandpower()”

我忘记在 bandpower.h、bandpower_impl.h 或 bandpower_impl.cc 中写什么?

【问题讨论】:

    标签: c++ eclipse ubuntu block gnuradio


    【解决方案1】:

    普通OOT布局的公共API在bandpower.h,所以必须加一个

    virtual double get_bandpower() = 0;
    

    在那个文件中。

    然后,您像您一样在_impl.cc/_impl.h 中重载/实现它。

    顺便说一句,我稍微反对你的实现背后的数学:作为noutput_items,即。在在“涓涓细流”的情况下,长度会小得多(在极端情况下会降至noutput_items==1)。因此,您的功率估算器的方差将取决于计算方面。

    这不是一件好事。更好地处理平均数量恒定的项目。在您的情况下,您可以使用set_output_multiple(因为接收器也是同步块,这也会影响输入倍数)来保证您始终获得固定数字的倍数。

    除此之外,已经有块可以做你想做的:

    • Probe Avg Mag²:有一个方法 level() 与您的 get_bandpower 相同(除了 √(.) )
    • Complex to Mag抽取 FIR 滤波器探测信号:在将 √(Re²+Im²) 传递到具有 123 的滤波器之前(这只是我的任意固定长度)1/长度的抽头,并在每个平均值中将其抽取到一个值。结果被发送到具有signal() 方法的Signal Probe,该方法执行您的get_bandpower 所做的事情。 CPU 负载相对较小——实际上只是每个样本的量级,然后每 123 个样本进行 123 个实数乘法 + 123 个实数加法,在过滤器中,所有 SIMD 都增加了,所以基本上,每个样本少于 1 个 FMAC。
    • 复杂到 Mag移动平均线探测信号:名称说明了一切。这里没有什么神奇的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-08
      • 2020-01-09
      • 2016-07-17
      • 1970-01-01
      • 2018-04-10
      • 2017-01-21
      • 1970-01-01
      • 2021-07-05
      相关资源
      最近更新 更多