gr_pn_correlator_ccの調査

「gr_pn_correlator_ccの調査」の編集履歴(バックアップ)一覧に戻る

gr_pn_correlator_ccの調査 - (2011/06/18 (土) 04:08:38) のソース

*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を作る!!
----