diff options
Diffstat (limited to 'gr-digital/lib')
-rw-r--r-- | gr-digital/lib/digital_constellation_receiver_cb.cc | 135 | ||||
-rw-r--r-- | gr-digital/lib/digital_constellation_receiver_cb.h | 156 | ||||
-rw-r--r-- | gr-digital/lib/digital_costas_loop_cc.cc | 1 | ||||
-rw-r--r-- | gr-digital/lib/digital_costas_loop_cc.h | 7 |
4 files changed, 259 insertions, 40 deletions
diff --git a/gr-digital/lib/digital_constellation_receiver_cb.cc b/gr-digital/lib/digital_constellation_receiver_cb.cc index 56385f11e..e2b6bf1d8 100644 --- a/gr-digital/lib/digital_constellation_receiver_cb.cc +++ b/gr-digital/lib/digital_constellation_receiver_cb.cc @@ -40,28 +40,151 @@ digital_constellation_receiver_cb_sptr digital_make_constellation_receiver_cb(digital_constellation_sptr constell, - float alpha, float beta, - float fmin, float fmax) + float loop_bw, float fmin, float fmax) { return gnuradio::get_initial_sptr(new digital_constellation_receiver_cb (constell, - alpha, beta, + loop_bw, fmin, fmax)); } static int ios[] = {sizeof(char), sizeof(float), sizeof(float), sizeof(float)}; static std::vector<int> iosig(ios, ios+sizeof(ios)/sizeof(int)); digital_constellation_receiver_cb::digital_constellation_receiver_cb (digital_constellation_sptr constellation, - float alpha, float beta, - float fmin, float fmax) + float loop_bw, float fmin, float fmax) : gr_block ("constellation_receiver_cb", gr_make_io_signature (1, 1, sizeof (gr_complex)), gr_make_io_signaturev (1, 4, iosig)), + d_freq(0), d_max_freq(fmax), d_min_freq(fmin), d_phase(0), d_constellation(constellation), - d_alpha(alpha), d_beta(beta), d_freq(0), d_max_freq(fmax), d_min_freq(fmin), d_phase(0), d_current_const_point(0) { if (d_constellation->dimensionality() != 1) throw std::runtime_error ("This receiver only works with constellations of dimension 1."); + + // Set the damping factor for a critically damped system + d_damping = sqrtf(2.0f)/2.0f; + + // Set the bandwidth, which will then call update_gains() + set_loop_bandwidth(loop_bw); +} + + +/******************************************************************* + SET FUNCTIONS +*******************************************************************/ + +void +digital_constellation_receiver_cb::set_loop_bandwidth(float bw) +{ + if(bw < 0) { + throw std::out_of_range ("digital_constellation_receiver_cb: invalid bandwidth. Must be >= 0."); + } + + d_loop_bw = bw; + update_gains(); +} + +void +digital_constellation_receiver_cb::set_damping_factor(float df) +{ + if(df < 0 || df > 1.0) { + throw std::out_of_range ("digital_constellation_receiver_cb: invalid damping factor. Must be in [0,1]."); + } + + d_damping = df; + update_gains(); +} + +void +digital_constellation_receiver_cb::set_alpha(float alpha) +{ + if(alpha < 0 || alpha > 1.0) { + throw std::out_of_range ("digital_constellation_receiver_cb: invalid alpha. Must be in [0,1]."); + } + d_alpha = alpha; +} + +void +digital_constellation_receiver_cb::set_beta(float beta) +{ + if(beta < 0 || beta > 1.0) { + throw std::out_of_range ("digital_constellation_receiver_cb: invalid beta. Must be in [0,1]."); + } + d_beta = beta; +} + +void +digital_constellation_receiver_cb::set_frequency(float freq) +{ + if(freq > d_max_freq) + d_freq = d_min_freq; + else if(freq < d_min_freq) + d_freq = d_max_freq; + else + d_freq = freq; +} + +void +digital_constellation_receiver_cb::set_phase(float phase) +{ + d_phase = phase; + while(d_phase>M_TWOPI) + d_phase -= M_TWOPI; + while(d_phase<-M_TWOPI) + d_phase += M_TWOPI; +} + + +/******************************************************************* + GET FUNCTIONS +*******************************************************************/ + + +float +digital_constellation_receiver_cb::get_loop_bandwidth() const +{ + return d_loop_bw; +} + +float +digital_constellation_receiver_cb::get_damping_factor() const +{ + return d_damping; +} + +float +digital_constellation_receiver_cb::get_alpha() const +{ + return d_alpha; +} + +float +digital_constellation_receiver_cb::get_beta() const +{ + return d_beta; +} + +float +digital_constellation_receiver_cb::get_frequency() const +{ + return d_freq; +} + +float +digital_constellation_receiver_cb::get_phase() const +{ + return d_phase; +} + +/******************************************************************* +*******************************************************************/ + +void +digital_constellation_receiver_cb::update_gains() +{ + float denom = (1.0 + 2.0*d_damping*d_loop_bw + d_loop_bw*d_loop_bw); + d_alpha = (4*d_damping*d_loop_bw) / denom; + d_beta = (4*d_loop_bw*d_loop_bw) / denom; } void diff --git a/gr-digital/lib/digital_constellation_receiver_cb.h b/gr-digital/lib/digital_constellation_receiver_cb.h index bf6fc51fa..ea55c6243 100644 --- a/gr-digital/lib/digital_constellation_receiver_cb.h +++ b/gr-digital/lib/digital_constellation_receiver_cb.h @@ -35,8 +35,7 @@ typedef boost::shared_ptr<digital_constellation_receiver_cb> digital_constellati // public constructor digital_constellation_receiver_cb_sptr digital_make_constellation_receiver_cb (digital_constellation_sptr constellation, - float alpha, float beta, - float fmin, float fmax); + float loop_bw, float fmin, float fmax); /*! * \brief This block takes care of receiving generic modulated signals through phase, frequency, and symbol @@ -73,31 +72,124 @@ class digital_constellation_receiver_cb : public gr_block gr_vector_void_star &output_items); - // Member function related to the phase/frequency tracking portion of the receiver - //! (CL) Returns the value for alpha (the phase gain term) - float alpha() const { return d_alpha; } - - //! (CL) Returns the value of beta (the frequency gain term) - float beta() const { return d_beta; } + /******************************************************************* + SET FUNCTIONS + *******************************************************************/ - //! (CL) Returns the current value of the frequency of the NCO in the Costas loop - float freq() const { return d_freq; } + /*! + * \brief Set the loop bandwidth + * + * Set the loop filter's bandwidth to \p bw. This should be between + * 2*pi/200 and 2*pi/100 (in rads/samp). It must also be a positive + * number. + * + * When a new damping factor is set, the gains, alpha and beta, of the loop + * are recalculated by a call to update_gains(). + * + * \param bw (float) new bandwidth + * + */ + void set_loop_bandwidth(float bw); - //! (CL) Returns the current value of the phase of the NCO in the Costal loop - float phase() const { return d_phase; } + /*! + * \brief Set the loop damping factor + * + * Set the loop filter's damping factor to \p df. The damping factor + * should be sqrt(2)/2.0 for critically damped systems. + * Set it to anything else only if you know what you are doing. It must + * be a number between 0 and 1. + * + * When a new damping factor is set, the gains, alpha and beta, of the loop + * are recalculated by a call to update_gains(). + * + * \param df (float) new damping factor + * + */ + void set_damping_factor(float df); - //! (CL) Sets the value for alpha (the phase gain term) - void set_alpha(float alpha) { d_alpha = alpha; } - - //! (CL) Setss the value of beta (the frequency gain term) - void set_beta(float beta) { d_beta = beta; } + /*! + * \brief Set the loop gain alpha + * + * Set's the loop filter's alpha gain parameter. + * + * This value should really only be set by adjusting the loop bandwidth + * and damping factor. + * + * \param alpha (float) new alpha gain + * + */ + void set_alpha(float alpha); - //! (CL) Sets the current value of the frequency of the NCO in the Costas loop - void set_freq(float freq) { d_freq = freq; } + /*! + * \brief Set the loop gain beta + * + * Set's the loop filter's beta gain parameter. + * + * This value should really only be set by adjusting the loop bandwidth + * and damping factor. + * + * \param beta (float) new beta gain + * + */ + void set_beta(float beta); - //! (CL) Setss the current value of the phase of the NCO in the Costal loop - void set_phase(float phase) { d_phase = phase; } + /*! + * \brief Set the phase/freq recovery loop's frequency. + * + * Set's the phase/freq recovery loop's frequency. While this is normally + * updated by the inner loop of the algorithm, it could be useful to + * manually initialize, set, or reset this under certain circumstances. + * + * \param freq (float) new frequency + * + */ + void set_frequency(float freq); + /*! + * \brief Set the phase/freq recovery loop's phase. + * + * Set's the phase/freq recovery loop's phase. While this is normally + * updated by the inner loop of the algorithm, it could be useful to + * manually initialize, set, or reset this under certain circumstances. + * + * \param phase (float) new phase + * + */ + void set_phase(float phase); + + /******************************************************************* + GET FUNCTIONS + *******************************************************************/ + + /*! + * \brief Returns the loop bandwidth + */ + float get_loop_bandwidth() const; + + /*! + * \brief Returns the loop damping factor + */ + float get_damping_factor() const; + + /*! + * \brief Returns the loop gain alpha + */ + float get_alpha() const; + + /*! + * \brief Returns the loop gain beta + */ + float get_beta() const; + + /*! + * \brief Get the phase/freq recovery loop's frequency estimate + */ + float get_frequency() const; + + /*! + * \brief Get the phase/freq loop's phase estimate + */ + float get_phase() const; protected: @@ -114,8 +206,7 @@ protected: * work loop based on the value of M. */ digital_constellation_receiver_cb (digital_constellation_sptr constellation, - float alpha, float beta, - float fmin, float fmax); + float loop_bw, float fmin, float fmax); void phase_error_tracking(float phase_error); @@ -123,11 +214,14 @@ protected: unsigned int d_M; // Members related to carrier and phase tracking - float d_alpha; - float d_beta; float d_freq, d_max_freq, d_min_freq; float d_phase; + float d_loop_bw; + float d_damping; + float d_alpha; + float d_beta; + digital_constellation_sptr d_constellation; unsigned int d_current_const_point; @@ -140,10 +234,18 @@ protected: //! index to delay line unsigned int d_dl_idx; + /*! \brief update the system gains from the loop bandwidth and damping factor + * + * This function updates the system gains based on the loop + * bandwidth and damping factor of the system. + * These two factors can be set separately through their own + * set functions. + */ + void update_gains(); + friend digital_constellation_receiver_cb_sptr digital_make_constellation_receiver_cb (digital_constellation_sptr constell, - float alpha, float beta, - float fmin, float fmax); + float loop_bw, float fmin, float fmax); }; #endif diff --git a/gr-digital/lib/digital_costas_loop_cc.cc b/gr-digital/lib/digital_costas_loop_cc.cc index be914486f..af9e20ac8 100644 --- a/gr-digital/lib/digital_costas_loop_cc.cc +++ b/gr-digital/lib/digital_costas_loop_cc.cc @@ -46,7 +46,6 @@ digital_costas_loop_cc::digital_costas_loop_cc (float loop_bw, int order gr_make_io_signature (1, 1, sizeof (gr_complex)), gr_make_io_signature2 (1, 2, sizeof (gr_complex), sizeof(float))), d_max_freq(1.0), d_min_freq(-1.0), - d_loop_bw(loop_bw), d_order(order), d_phase_detector(NULL) { // Set the damping factor for a critically damped system diff --git a/gr-digital/lib/digital_costas_loop_cc.h b/gr-digital/lib/digital_costas_loop_cc.h index faf5e4263..83edded19 100644 --- a/gr-digital/lib/digital_costas_loop_cc.h +++ b/gr-digital/lib/digital_costas_loop_cc.h @@ -93,7 +93,7 @@ class digital_costas_loop_cc : public gr_sync_block digital_costas_loop_cc (float loop_bw, int order ) throw (std::invalid_argument); - /*! \brief update the system gains from omega and eta + /*! \brief update the system gains from the loop bandwidth and damping factor * * This function updates the system gains based on the loop * bandwidth and damping factor of the system. @@ -249,11 +249,6 @@ public: int work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); - - /*! \brief returns the current NCO frequency in radians/sample - * - */ - float freq() const { return d_freq; } }; #endif |