【问题标题】:GNU Radio no output from other blocks parallel with my own OOT blockGNU Radio 没有来自与我自己的 OOT 块并行的其他块的输出
【发布时间】:2016-06-09 14:26:42
【问题描述】:

我想用 C++ 为 GNU Radio 编写我自己的带有 1 个输入和 1 个输出的通用块。我使用 gr_modtool 遵循了 gnuradio.org 中的步骤。它可以很好地工作。但是当我将其他块(范围 sink2)与相同的源连接时,其中没有输出。

我将流程图连接为:

                            /-> Scope Sink2
Signal Source -> Throttle -|
                            \-> my own block -> Scope Sink1

我正在使用 GNU Radio Companion v3.7.6.1-65-g500517ac

我创建了块“energy_de”。这将在其他四个文件中创建: energy_de.h

#ifndef INCLUDED_CPP_ENERGY_DE_H
#define INCLUDED_CPP_ENERGY_DE_H

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

namespace gr {
  namespace cpp {

    /*!
     * \brief <+description of block+>
     * \ingroup cpp
     *
     */
    class CPP_API energy_de : virtual public gr::block
    {
     public:
      typedef boost::shared_ptr<energy_de> sptr;

      /*!
       * \brief Return a shared_ptr to a new instance of cpp::energy_de.
       *
       * To avoid accidental use of raw pointers, cpp::energy_de's
       * constructor is in a private implementation
       * class. cpp::energy_de::make is the public interface for
       * creating new instances.
       */
      static sptr make(float makenoise);

      virtual float noise () const = 0;
      virtual void set_noise (float noise) = 0;
    };

  } // namespace cpp
} // namespace gr

energy_de_impl.h

#ifndef INCLUDED_CPP_ENERGY_DE_IMPL_H
#define INCLUDED_CPP_ENERGY_DE_IMPL_H

#include <cpp/energy_de.h>

namespace gr {
  namespace cpp {

    class energy_de_impl : public energy_de
    {
     private:
      float d_noise;

     public:
      energy_de_impl(float noise);
      ~energy_de_impl();

      // Where all the action really happens
      void forecast (int noutput_items, gr_vector_int &ninput_items_required);
      float noise() const { return d_noise; }
      void set_noise(float noise) { d_noise = noise; }

      int general_work(int noutput_items,
               gr_vector_int &ninput_items,
               gr_vector_const_void_star &input_items,
               gr_vector_void_star &output_items);
    };

  } // namespace cpp
} // namespace gr

energy_de_impl.cc

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

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

namespace gr {
  namespace cpp {

    energy_de::sptr
    energy_de::make(float noise)
    {
      return gnuradio::get_initial_sptr
        (new energy_de_impl(noise));
    }

    /*
     * The private constructor
     */
    energy_de_impl::energy_de_impl(float noise)
      : gr::block("energy_de",
              gr::io_signature::make(1, 1, sizeof(float)),
              gr::io_signature::make(1, 1, sizeof(float))),
        d_noise(noise)
    {
    }

    /*
     * Our virtual destructor.
     */
    energy_de_impl::~energy_de_impl()
    {
    }

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

    int
    energy_de_impl::general_work (int noutput_items,
                       gr_vector_int &ninput_items,
                       gr_vector_const_void_star &input_items,
                       gr_vector_void_star &output_items)
    {
        const float *in = (const float *) input_items[0];
        float *out = (float *) output_items[0];

        for(int i = 0; i < noutput_items; i++){
            if (in[i]*in[i] > d_noise){
              out[i] = 1.0;
            }
            else{
              out[i] = 0.0;
            }
        }

        return noutput_items;
    }

  } /* namespace cpp */
} /* namespace gr */

cpp_energy_de.xml

<?xml version="1.0"?>
<block>
  <name>energy_de</name>
  <key>cpp_energy_de</key>
  <category>cpp</category>
  <import>import cpp</import>
  <make>cpp.energy_de($noise)</make>
  <callback>set_niose($noise)</callback>

  <param>
    <name>noise</name>
    <key>noise</key>
    <type>float</type>
  </param>


  <sink>
    <name>in</name>
    <type>float</type>
  </sink>

  <source>
    <name>out</name>
    <type>float</type>
  </source>
</block>

为什么我无法从 Scope Sink2 获得输出?我忘了在四个文件中写什么?这是关于我的块的 input_items 缓冲区的问题吗?

【问题讨论】:

    标签: c++ block gnuradio gnuradio-companion


    【解决方案1】:

    当使用一般的block而不是sync_block时,你的general_work必须调用consume,表明你已经阅读了多少项目,否则你自己块的输入缓冲区( == 油门的输出缓冲区)迅速填满,油门无法将新样本放入其中,并且您的流程图停止。此时,您的示波器接收器可能根本没有足够的输入来显示任何内容。

    我认为对于您的用例,仅使用 sync_block 会容易得多,因此是正确的方法。

    我想告诉你一个mail 我今天写信给discuss GNU Radio mailing list。它解释了这背后的缓冲区空间概念。

                  /->A->Null Sink
    File Source -|
                  \->B->File Sink
    

    [...]

    所以下面的机制是:File Source 的输出缓冲区是 A的输入缓冲区和B的输入缓冲区。没有内存重复 在这里。

    文件源有一个带写指针的缓冲区写入器,A 和 B 有 他们自己的指向该缓冲区的读指针。

    当 File Source 产生 N 项时,写指针前进 N。

    同样,当 A 消费 M 个项目时,A 的读指针前进 M。

    当调用 (general_)work 时,input_items 缓冲区是 (are) 真的 只是一个指针(start_of_buffer + 读指针)。等效地, output_items 缓冲区(s)实际上只是指向写入 指针。

    文件源只允许产生如此多的项目,以至于写指针不会超过最小读指针,因为在这种情况下,它会覆盖下游块尚未消耗的样本。

    【讨论】:

    • 非常感谢!使用“消费”后,我从示波器 sink2 接收到信号。
    猜你喜欢
    • 2018-01-01
    • 2020-01-09
    • 2016-06-17
    • 2021-01-11
    • 1970-01-01
    • 2016-06-15
    • 2019-12-11
    • 2019-12-16
    • 2016-07-17
    相关资源
    最近更新 更多