gr_pn_correlator_ccの調査

pn系列で直接逆拡散するブロックを作る

gr_pn_correlator_cc.h
#ifndef INCLUDED_GR_PN_CORRELATOR_CC_H
#define INCLUDED_GR_PN_CORRELATOR_CC_H

#include <gr_sync_decimator.h>
#include <gri_glfsr.h>

class gr_pn_correlator_cc;
typedef boost::shared_ptr<gr_pn_correlator_cc> gr_pn_correlator_cc_sptr;

gr_pn_correlator_cc_sptr
gr_make_pn_correlator_cc(int degree, int mask=0, int seed=1);
/*!
 * \brief PN code sequential search correlator
 *
 * \ingroup sync_blk
 * Receives complex baseband signal, outputs complex correlation against
 * reference PN code, one sample per PN code period
 */

class gr_pn_correlator_cc : public gr_sync_decimator
{
  friend gr_pn_correlator_cc_sptr gr_make_pn_correlator_cc(int degree, int mask, int seed); 

  int        d_len;
  float      d_pn;
  gri_glfsr *d_reference; 

 protected:
  gr_pn_correlator_cc(int degree, int mask, int seed);

 public:
  virtual int work(int noutput_items,
		   gr_vector_const_void_star &input_items,
		   gr_vector_void_star &output_items);

  ~gr_pn_correlator_cc();
};

#endif /* INCLUDED_GR_PN_CORRELATOR_CC_H */

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

#include <gr_pn_correlator_cc.h>
#include <gr_io_signature.h>

gr_pn_correlator_cc_sptr
gr_make_pn_correlator_cc(int degree, int mask, int seed)
{
  return gr_pn_correlator_cc_sptr (new gr_pn_correlator_cc(degree, mask, seed));
}
//コンストラクタ
gr_pn_correlator_cc::gr_pn_correlator_cc(int degree, int mask, int seed)
  : gr_sync_decimator ("pn_correlator_cc",
		       gr_make_io_signature (1, 1, sizeof(gr_complex)),
		       gr_make_io_signature (1, 1, sizeof(gr_complex)),
		       (unsigned int)((1ULL << degree)-1)) // PN code length
{
  d_len = (unsigned int)((1ULL << degree)-1); //1を左にdegreeビット移動させて1引く(?):PN系列長を示す。
  if (mask == 0)
    mask = gri_glfsr::glfsr_mask(degree); //マスクの指定がない場合はdegreeからmaskを作る
  d_reference = new gri_glfsr(mask, seed); //ガロアLFSRを使ってpn発生器をインスタンス化
  for (int i = 0; i < d_len; i++)	// initialize to last value in sequence
    d_pn = 2.0*d_reference->next_bit()-1.0;//シーケンスの最後の値で初期化されている!!そりゃずれるわ。。
}

gr_pn_correlator_cc::~gr_pn_correlator_cc()
{
  delete d_reference;
}

int gr_pn_correlator_cc::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];
  gr_complex sum;

  for (int i = 0; i < noutput_items; i++) { //出力信号分のループ
    sum = 0.0;

    for (int j = 0; j < d_len; j++) { //PN系列のタップ数分だけループ
      if (j != 0)		            // PN生成器を1サンプル分遅らせる。これがあることでd_len-1個しか掛け合わされない。。
	d_pn = 2.0*d_reference->next_bit()-1.0; // no conditionals
      sum += (*in)++ * d_pn; //各PN系列のチップを入力に掛けて、合計をとっている。
    }

    *out++ = sum*gr_complex(1.0/d_len, 0.0); //正規化
  }

  return noutput_items;
}
なぜか最初からPN生成器が1サンプルずれている。最初の1周期が終わると、今後は2サンプルずれた結果がでる。。これでシンボル同期を取っている!!
このブロックを使ってdescrambleさせた時の出力結果
degree = 4(4次のLFSR), mask=0とseed=2に設定
送信信号:src_data = (1+1j,×15個)
in[0]=-0.0666667+-0.0666667j, out[0]=-0.0666667+-0.0666667j
in[1]=-0.0666667+-0.0666667j, out[1]=-0.0666667+-0.0666667j
in[2]=-0.0666667+-0.0666667j, out[2]=-0.0666667+-0.0666667j
in[3]=-0.0666667+-0.0666667j, out[3]=-0.0666667+-0.0666667j
in[4]=-0.0666667+-0.0666667j, out[4]=-0.0666667+-0.0666667j
in[5]=-0.0666667+-0.0666667j, out[5]=-0.0666667+-0.0666667j
in[6]=-0.0666667+-0.0666667j, out[6]=-0.0666667+-0.0666667j
in[7]=-0.0666667+-0.0666667j, out[7]=-0.0666667+-0.0666667j
noutput_items = 4
in[0]=-0.0666667+-0.0666667j, out[0]=-0.0666667+-0.0666667j
in[1]=-0.0666667+-0.0666667j, out[1]=-0.0666667+-0.0666667j
in[2]=-0.0666667+-0.0666667j, out[2]=-0.0666667+-0.0666667j
in[3]=-0.0666667+-0.0666667j, out[3]=-0.0666667+-0.0666667j
noutput_items = 2
in[0]=-0.0666667+-0.0666667j, out[0]=-0.0666667+-0.0666667j
in[1]=-0.0666667+-0.0666667j, out[1]=-0.0666667+-0.0666667j
noutput_items = 1
in[0]=1+1j, out[0]=1+1j
やっぱり15個目のシンボルだけ同期が取れてる!!
ここではgri_glfsr(ガロアLFSR)を使っているので、念のためglfsrを使った拡散ブロックを作っといた(how_interp_gscrambler_cc)。
以下、gri_glfsr.h
#ifndef INCLUDED_GRI_GLFSR_H
#define INCLUDED_GRI_GLFSR_H

/*!
 * \brief Galois Linear Feedback Shift Register using specified polynomial mask
 * \ingroup misc
 *
 * Generates a maximal length pseudo-random sequence of length 2^degree-1
 */

class gri_glfsr
{
 private:
  int d_shift_register;
  int d_mask;

 public:

  gri_glfsr(int mask, int seed) { d_shift_register = seed; d_mask = mask; }
  static int glfsr_mask(int degree); 

  unsigned char next_bit() {
    unsigned char bit = d_shift_register & 1;
    d_shift_register >>= 1;
    if (bit) //なぜここで出力ビットが0の場合はやらないのか??
      d_shift_register ^= d_mask; //d_shift_registerとd_maskの排他的論理和をd_shift_registerに入れる
    return bit;
  }

  int mask() const { return d_mask; }
};

#endif /* INCLUDED_GRI_GLFSR_H */
こいつをいじってhowto_decim_gdescrambler_ccを作る!!

最終更新:2011年06月18日 04:08