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

表示オプション

横に並べて表示:
変化行の前後のみ表示: