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