diff options
author | Tom Rondeau <trondeau@vt.edu> | 2011-08-14 22:32:01 -0400 |
---|---|---|
committer | Tom Rondeau <trondeau@vt.edu> | 2011-08-14 22:32:01 -0400 |
commit | ed564be6c78a3e22b3c98862834192f8b20bc551 (patch) | |
tree | c566277b3a39699669eb684156d09aedae1925be /gr-digital/lib | |
parent | 7e47bddafc6b27c623137c6d76f460e608952fcc (diff) |
digital: cleaned up Costas loop code by switching over to the gri_control_loop class to handle the inner loop. Had to add it to digital_swig.i to properly wrap the parent functions into Python.
Diffstat (limited to 'gr-digital/lib')
-rw-r--r-- | gr-digital/lib/digital_costas_loop_cc.cc | 167 | ||||
-rw-r--r-- | gr-digital/lib/digital_costas_loop_cc.h | 143 |
2 files changed, 10 insertions, 300 deletions
diff --git a/gr-digital/lib/digital_costas_loop_cc.cc b/gr-digital/lib/digital_costas_loop_cc.cc index af9e20ac83..370dc7e5c1 100644 --- a/gr-digital/lib/digital_costas_loop_cc.cc +++ b/gr-digital/lib/digital_costas_loop_cc.cc @@ -30,8 +30,6 @@ #include <gr_sincos.h> #include <gr_math.h> -#define M_TWOPI (2*M_PI) - digital_costas_loop_cc_sptr digital_make_costas_loop_cc (float loop_bw, int order ) throw (std::invalid_argument) @@ -45,15 +43,9 @@ digital_costas_loop_cc::digital_costas_loop_cc (float loop_bw, int order : gr_sync_block ("costas_loop_cc", 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), + gri_control_loop(loop_bw, 1.0, -1.0), d_order(order), d_phase_detector(NULL) { - // 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 up the phase detector to use based on the constellation order switch(d_order) { case 2: @@ -72,10 +64,6 @@ digital_costas_loop_cc::digital_costas_loop_cc (float loop_bw, int order throw std::invalid_argument("order must be 2, 4, or 8"); break; } - - // Initialize loop values - d_freq = 0; - d_phase = 0; } float @@ -119,126 +107,6 @@ digital_costas_loop_cc::phase_detector_2(gr_complex sample) const return (sample.real()*sample.imag()); } -/******************************************************************* - SET FUNCTIONS -*******************************************************************/ - -void -digital_costas_loop_cc::set_loop_bandwidth(float bw) -{ - if(bw < 0) { - throw std::out_of_range ("digital_costas_loop_cc: invalid bandwidth. Must be >= 0."); - } - - d_loop_bw = bw; - update_gains(); -} - -void -digital_costas_loop_cc::set_damping_factor(float df) -{ - if(df < 0 || df > 1.0) { - throw std::out_of_range ("digital_costas_loop_cc: invalid damping factor. Must be in [0,1]."); - } - - d_damping = df; - update_gains(); -} - -void -digital_costas_loop_cc::set_alpha(float alpha) -{ - if(alpha < 0 || alpha > 1.0) { - throw std::out_of_range ("digital_costas_loop_cc: invalid alpha. Must be in [0,1]."); - } - d_alpha = alpha; -} - -void -digital_costas_loop_cc::set_beta(float beta) -{ - if(beta < 0 || beta > 1.0) { - throw std::out_of_range ("digital_costas_loop_cc: invalid beta. Must be in [0,1]."); - } - d_beta = beta; -} - -void -digital_costas_loop_cc::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_costas_loop_cc::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_costas_loop_cc::get_loop_bandwidth() const -{ - return d_loop_bw; -} - -float -digital_costas_loop_cc::get_damping_factor() const -{ - return d_damping; -} - -float -digital_costas_loop_cc::get_alpha() const -{ - return d_alpha; -} - -float -digital_costas_loop_cc::get_beta() const -{ - return d_beta; -} - -float -digital_costas_loop_cc::get_frequency() const -{ - return d_freq; -} - -float -digital_costas_loop_cc::get_phase() const -{ - return d_phase; -} - - -/******************************************************************* -*******************************************************************/ - - -void -digital_costas_loop_cc::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; -} - int digital_costas_loop_cc::work (int noutput_items, gr_vector_const_void_star &input_items, @@ -262,18 +130,9 @@ digital_costas_loop_cc::work (int noutput_items, error = (*this.*d_phase_detector)(optr[i]); error = gr_branchless_clip(error, 1.0); - d_freq = d_freq + d_beta * error; - d_phase = d_phase + d_freq + d_alpha * error; - - while(d_phase>M_TWOPI) - d_phase -= M_TWOPI; - while(d_phase<-M_TWOPI) - d_phase += M_TWOPI; - - if (d_freq > d_max_freq) - d_freq = d_min_freq; - else if (d_freq < d_min_freq) - d_freq = d_max_freq; + advance_loop(error); + phase_wrap(); + frequency_limit(); foptr[i] = d_freq; } @@ -284,20 +143,10 @@ digital_costas_loop_cc::work (int noutput_items, error = (*this.*d_phase_detector)(optr[i]); error = gr_branchless_clip(error, 1.0); - - d_freq = d_freq + d_beta * error; - d_phase = d_phase + d_freq + d_alpha * error; - - while(d_phase>M_TWOPI) - d_phase -= M_TWOPI; - while(d_phase<-M_TWOPI) - d_phase += M_TWOPI; - - if (d_freq > d_max_freq) - d_freq = d_min_freq; - else if (d_freq < d_min_freq) - d_freq = d_max_freq; - + + advance_loop(error); + phase_wrap(); + frequency_limit(); } } return noutput_items; diff --git a/gr-digital/lib/digital_costas_loop_cc.h b/gr-digital/lib/digital_costas_loop_cc.h index 83edded194..7b2cd6dad7 100644 --- a/gr-digital/lib/digital_costas_loop_cc.h +++ b/gr-digital/lib/digital_costas_loop_cc.h @@ -25,6 +25,7 @@ #define INCLUDED_DIGITAL_COSTAS_LOOP_CC_H #include <gr_sync_block.h> +#include <gri_control_loop.h> #include <stdexcept> #include <fstream> @@ -72,36 +73,17 @@ digital_make_costas_loop_cc (float loop_bw, int order * * \p order must be 2 or 4. */ -class digital_costas_loop_cc : public gr_sync_block +class digital_costas_loop_cc : public gr_sync_block, public gri_control_loop { friend digital_costas_loop_cc_sptr digital_make_costas_loop_cc (float loop_bw, int order ) throw (std::invalid_argument); - float d_max_freq; - float d_min_freq; int d_order; - float d_loop_bw; - float d_damping; - float d_alpha; - float d_beta; - - float d_phase; - float d_freq; - digital_costas_loop_cc (float loop_bw, int order ) throw (std::invalid_argument); - /*! \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(); - /*! \brief the phase detector circuit for 8th-order PSK loops * \param sample complex sample * \return the phase error @@ -125,127 +107,6 @@ class digital_costas_loop_cc : public gr_sync_block public: - /******************************************************************* - SET FUNCTIONS - *******************************************************************/ - - /*! - * \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); - - /*! - * \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); - - /*! - * \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); - - /*! - * \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); - - /*! - * \brief Set the Costas loop's frequency. - * - * Set's the Costas 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 Costas loop's phase. - * - * Set's the Costas 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 Costas loop's frequency estimate - */ - float get_frequency() const; - - /*! - * \brief Get the Costas loop's phase estimate - */ - float get_phase() const; - - int work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); |