如何在C ++中将GRC块“随机源”的字节输出数据正确读取到自己的OOT块中?

时间:2019-08-02 14:02:47

标签: c++ gnuradio gnuradio-companion

我正在gnuradio-companion中迈出第一步,并希望用c ++编写自己的三个模块以进行信号处理。我完成了gnuradio教程,并且对c ++有所了解,但我不是专家。

系统设置: Ubuntu 18.04.2 LTS GNU Radio-Companion 3.7.13.4

我想使用grc块“ Random Source”生成字节,并将其传递给三个插值器,以创建脉冲位置符号。

“随机源”块的配置如下: 最小值:0 最大值:4(2 ^ M = ppm符号中的脉冲位置计数) 样本数:16或32 重复:是

我的三分之一块是c ++中的插值块,具有一个输入和一个输出。构造函数中的插值值为6000,这表示input:output的关系船为1:6000。 函数将输入in [0]作为参数,并生成一个类型为gr_complex的向量,其中脉冲位于in [0]的值的位置处,该值可以为[0,1,2,3]。具有ppm符号的向量将返回到work()函数。

观察到的问题: 第一个问题:如果“随机源”生成一个值为0x00的字节,并且我使用std :: cout打印in [0]的值,则在运行gnuradio-companion的终端窗口中将显示以下错误:

/home/xyz/software/gnuradio/lib/python2.7/dist-packages/gnuradio/grc/gui/Dialogs.py:65:GtkWarning:gtk_text_buffer_emit_insert:断言'g_utf8_validate(text,len,NULL)'失败   self.get_buffer()。insert(self.get_buffer()。get_end_iter(),行)

解决方案:我的解决方案是将in [0]的值复制到整数变量中。 std :: cout会按预期输出值。

第二个问题:如果我将“随机源”的Num Samples设置为16到32或更高,并使用std :: cout在终端中查看in [0]的值(将其复制到int变量中),值与“随机来源”生成并显示在“ QT GUI时间槽”中的值不匹配。我真的不知道是什么原因引起的。

解决方案:到目前为止还没有解决方案...


这是我三分之二的代码

namespace gr {
  namespace newmodulator {

    pre_mod_v2::sptr
    pre_mod_v2::make(int M, float duty_cycle, int samples_per_symbol)
    {
      return gnuradio::get_initial_sptr
        (new pre_mod_v2_impl(M, duty_cycle, samples_per_symbol));
    }

    /*
     * The private constructor
     */
    pre_mod_v2_impl::pre_mod_v2_impl(int M, float duty_cycle, int samples_per_symbol)
      : gr::sync_interpolator("pre_mod_v2",
              gr::io_signature::make(1, 1, sizeof(char)),
              gr::io_signature::make(1, 1, sizeof(gr_complex)), samples_per_symbol + 94) /*, d_M(M), d_duty_cycle(duty_cycle), d_samples_per_symbol(samples_per_symbol)*/
    {
        d_M = M;
        d_duty_cycle = duty_cycle;
        d_samples_per_symbol = samples_per_symbol;

        //Variablen die in der Funktion set_vppm_symbol benötigt werden.
        count_slots_per_symbol = 0;
        vppm_slots = pow(2, M);
        samples_per_slot = samples_per_symbol / vppm_slots;
        pulse_length = (samples_per_symbol / 100 * duty_cycle);
        symbol_value = 0;

        //preamble = {{0, 5}, {0, 0}, {0, 0}, {0, 0}, {0, 5}};
        preamble = {{0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
        {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
        {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
        {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
        {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 1}, {0, 0}, {0, 0},
        {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
        {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
        {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
        {0, 0}, {0, 0}, {0, 0}, {0, 1}};
    }

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

    /* noutput_items = zahl (interpolation factor)
     */
    int
    pre_mod_v2_impl::work(int noutput_items,
        gr_vector_const_void_star &input_items,
        gr_vector_void_star &output_items)
    {
        /* es werden Zeiger deklariert, die auf die Startadresse von input_items und output_items zeigen.
         * Die Größe eines Zeigers wird durch typ* festgelegt
         * ninput_items hat nur ein Element,
         * während output_items so viele Elemente hat, wie oben durch den Interpolation-Faktor samples_per_symbol angegeben ist */
      const unsigned char *in = (const unsigned char *) input_items[0];
      gr_complex *out = (gr_complex *) output_items[0];

      //std::cout << "symbol_value: " << in[0] << std::endl;
      std::vector<gr_complex> vppm_symbols(d_samples_per_symbol + 94);

      vppm_symbols = set_vppm_symbol(in, d_M, d_duty_cycle, d_samples_per_symbol);


      //std::cout << "noutput_items: " << noutput_items << std::endl;

      for (int i = 0; i < noutput_items; i++)
      {
          out[i] = vppm_symbols[i];
      }

      // es werden insgesamt noutput_items verarbeitet
      consume_each(noutput_items);
      // Tell runtime system how many output items we produced.
      return noutput_items;
    }

    std::vector<gr_complex> pre_mod_v2_impl::set_vppm_symbol(const unsigned char* in, int &M, float &duty_cycle, int &samples_per_symbol)
    {
        symbol_value = in[0];

//        if (!symbol_value){
//            symbol_value = 0;
//        }

        std::cout << "symbol_value: " << static_cast<int>(in[0]) << std::endl;

        std::vector<gr_complex> vppm_symbol(samples_per_symbol);
        for (int i = (symbol_value * samples_per_slot); i < (symbol_value * samples_per_slot + pulse_length); i++)
        {
            vppm_symbol[i] = {static_cast<float>(1.0), 0};
        }

        vppm_symbol.insert(vppm_symbol.begin(), preamble.begin(), preamble.end());


        return vppm_symbol;
    }

  } /* namespace newmodulator */
} /* namespace gr */

1 个答案:

答案 0 :(得分:0)

好的,我解决了我的问题。我只是将我的函数set_vppm_symbol的代码添加到我的工作函数中,并删除了“ consume_each(noutput_items)”行,尽管在手册中将其描述为使用该函数让我很恼火。现在,我得到了预期的输出。