1

C++ で GNU Radio 用に 1 つの入力と 1 つの出力を持つ独自の汎用ブロックをコーディングしたいと考えています。gr_modtool を使用して、gnuradio.org の手順に従いました。それはうまく機能します。しかし、他のブロック(スコープシンク2)を同じソースに接続すると、出力がありません。

フロー グラフを次のように接続します。

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

GNU Radio Companion v3.7.6.1-65-g500517ac を使用しています

ブロック「energy_de」を作成しました。これにより、他の 4 つのファイルが作成されます。 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 から出力を取得できないのはなぜですか? 4 つのファイルの中で何を書き忘れましたか? これは私のブロックの input_items バッファに関する問題ですか?

4

1 に答える 1

1

blockではなくジェネラルを使用する場合はsync_block、を呼び出して、読み取ったアイテムの数を示すgeneral_work 必要consumeがあります。そうしないと、独自のブロックの入力バッファー (== スロットルの出力バッファー) がすぐにいっぱいになり、スロットルは新しいサンプルをそれに入れることができず、フローグラフが停止します。その時点で、スコープ シンクには何も表示するのに十分な入力がない可能性があります。

あなたのユースケースでは、 a を使用するだけsync_blockではるかに簡単になると思います。したがって、これを行う正しい方法です。

今日私がディスカッション GNU ラジオ メーリング リストに書いたメールを紹介したいと思います。この背後にあるバッファ スペースの概念について説明します。

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

[...]

したがって、以下のメカニズムは次のとおりです。File Source の出力バッファーは A の入力バッファーであり、B の入力バッファーです。ここではメモリの重複はありません。

File Source には、書き込みポインターを持つバッファー ライターがあり、A と B には、そのバッファーを指す独自の読み取りポインターがあります。

ファイル ソースが N 個のアイテムを生成する場合、書き込みポインターは N だけ進みます。

同様に、A が M 個のアイテムを消費すると、A の読み取りポインターは M だけ進みます。

(general_)work を呼び出すとき、input_items バッファーは、実際には単なるポインター (start_of_buffer + 読み取りポインター) です。同様に、output_items バッファーは、実際には書き込みポインターを指しているだけです。

ファイル ソースは、書き込みポインターが最小読み取りポインターを超えて進まないほど多くのアイテムを生成することしか許可されていません。

于 2016-02-26T11:52:50.490 に答える