GNU Radio 中的偏移 QPSK 检测 - 采样延迟

信息处理 数字通信 qpsk 格努拉迪奥
2022-02-23 02:52:32

OQPSK 检测器正在 GNU Radio 中进行测试。该架构是从 Michael Rice 的数字通信 - 离散时间方法中获得的。流程图如下所示。 流程图 调制器架构基本上是 QPSK 延迟采样率的一半,如下图所示。在流程图中,块 oqpskIQMap 将 I/Q 符号从 QPSK 映射到 OQPSK。它通过将 Q 通道延迟 d_delay 来实现这一点,d_delay 等于每个符号的样本数除以 2。

oqpskIQMap_impl::oqpskIQMap_impl(int sps)
      : gr::sync_block("oqpskIQMap",
              gr::io_signature::make(1, 1, sizeof(gr_complex)),
              gr::io_signature::make(1, 1, sizeof(gr_complex))),
        d_delay(sps/2)
    {
        //set_history(d_delay);
    }

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

    int
    oqpskIQMap_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];
      for(int i = 0; i < noutput_items; i++)
          out[i] = gr_complex(real(in[i]),imag(in[i - d_delay]));

      // Do <+signal processing+>

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

发送

Rice 书中的接收器架构如下所示。在这种架构中,匹配滤波器每个符号产生 2 个样本。oqpskIQDemap 块将输出样本 (X(KTs)、X(KTs + Ts/2)、Y(KTs) 和 Y(KTs + Ts/2) 处理成星座点 (X(KTs) ,Y(KTs + Ts) /2)),有效地将采样率降低到每个符号 1 个样本。

oqpskIQDemap_impl::oqpskIQDemap_impl(int delay)
      : gr::sync_decimator("oqpskIQDemap",
              gr::io_signature::make(1, 1, sizeof(gr_complex)),
              gr::io_signature::make(1, 1, sizeof(gr_complex)), 2),
        d_delay(delay)
    {}

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

    int
    oqpskIQDemap_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];

      for(int i = 0; i < noutput_items; i+=2)
          out[i] = gr_complex(real(in[i]),imag(in[i + 1]));

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

接收

传输的星座(顶部)看起来还不错。另一方面,考虑到 SNR 为 25 dBs,Rx 星座(底部)似乎有一些点出乎意料地越过了边界。我怀疑问题出在我在两个 IQ 映射/解映射块中引入延迟的方式上。

请让我知道你的想法。

问候,

星座

1个回答

感谢马库斯的回答,我能够解决这个问题。请参阅下面的更新代码:

智商映射

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

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

namespace gr {
  namespace oqpsk {

    oqpskIQMap::sptr
    oqpskIQMap::make(int sps)
    {
      return gnuradio::get_initial_sptr
        (new oqpskIQMap_impl(sps));
    }

    /*
     * The private constructor
     */
    oqpskIQMap_impl::oqpskIQMap_impl(int sps)
      : gr::sync_block("oqpskIQMap",
              gr::io_signature::make(1, 1, sizeof(gr_complex)),
              gr::io_signature::make(1, 1, sizeof(gr_complex))),
        d_delay(sps/2)
    {
        //set_history(1);
    }

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

    int
    oqpskIQMap_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];

      for(int i = d_delay; i < noutput_items; i++)
          out[i] = gr_complex(real(in[i]),imag(in[i - d_delay]));


      // Do <+signal processing+>

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

  } /* namespace oqpsk */
} /* namespace gr */

IQ Demapping 请注意,这是一个下采样模块,预计每个符号有 2 个样本,每个符号产生 1 个样本(单个星座点)。#ifdef HAVE_CONFIG_H #include "config.h" #endif

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

namespace gr {
  namespace oqpsk {

    oqpskIQDemap::sptr
    oqpskIQDemap::make(int delay)
    {
      return gnuradio::get_initial_sptr
        (new oqpskIQDemap_impl(delay));
    }

    /*
     * The private constructor
     */
    oqpskIQDemap_impl::oqpskIQDemap_impl(int delay)
      : gr::sync_decimator("oqpskIQDemap",
              gr::io_signature::make(1, 1, sizeof(gr_complex)),
              gr::io_signature::make(1, 1, sizeof(gr_complex)), 2),
        d_delay(delay)
    {
        set_output_multiple(2);
    }

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

    int
    oqpskIQDemap_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];

      //for(int i = 0; i < noutput_items; i+=2)
          //out[i] = gr_complex(real(in[i]),imag(in[i + 1]));
      out[0] = gr_complex(real(in[0]),imag(in[1]));

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

  } /* namespace oqpsk */
} /* namespace gr */

问候,