From 35fd5072f4a1eba6d02e3c4615dfde33783f876f Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Sat, 27 Aug 2011 16:30:56 -0400 Subject: digital: made digital constellation receiver a child of the second order control loop class and cleaned up the interface. --- .../lib/digital_constellation_receiver_cb.cc | 145 +-------------------- gr-digital/lib/digital_constellation_receiver_cb.h | 132 +------------------ 2 files changed, 9 insertions(+), 268 deletions(-) (limited to 'gr-digital/lib') diff --git a/gr-digital/lib/digital_constellation_receiver_cb.cc b/gr-digital/lib/digital_constellation_receiver_cb.cc index e2b6bf1d8..b9239962a 100644 --- a/gr-digital/lib/digital_constellation_receiver_cb.cc +++ b/gr-digital/lib/digital_constellation_receiver_cb.cc @@ -54,153 +54,20 @@ digital_constellation_receiver_cb::digital_constellation_receiver_cb (digital_co : 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), + gri_control_loop(loop_bw, fmax, fmin), d_constellation(constellation), 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 digital_constellation_receiver_cb::phase_error_tracking(float phase_error) { - d_freq += d_beta*phase_error; // adjust frequency based on error - d_phase += d_freq + d_alpha*phase_error; // adjust phase based on error - - // Make sure we stay within +-2pi - while(d_phase > M_TWOPI) - d_phase -= M_TWOPI; - while(d_phase < -M_TWOPI) - d_phase += M_TWOPI; - - // Limit the frequency range - d_freq = gr_branchless_clip(d_freq, d_max_freq); + advance_loop(phase_error); + phase_wrap(); + frequency_limit(); #if VERBOSE_COSTAS printf("cl: phase_error: %f phase: %f freq: %f sample: %f+j%f constellation: %f+j%f\n", @@ -236,10 +103,12 @@ digital_constellation_receiver_cb::general_work (int noutput_items, sample = in[i]; nco = gr_expj(d_phase); // get the NCO value for derotating the current sample sample = nco*sample; // get the downconverted symbol + sym_value = d_constellation->decision_maker_pe(&sample, &phase_error); - // phase_error = -arg(sample*conj(d_constellation->points()[sym_value])); phase_error_tracking(phase_error); // corrects phase and frequency offsets + out[i] = sym_value; + if(output_items.size() == 4) { out_err[i] = phase_error; out_phase[i] = d_phase; diff --git a/gr-digital/lib/digital_constellation_receiver_cb.h b/gr-digital/lib/digital_constellation_receiver_cb.h index ea55c6243..3885b301e 100644 --- a/gr-digital/lib/digital_constellation_receiver_cb.h +++ b/gr-digital/lib/digital_constellation_receiver_cb.h @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -63,7 +64,7 @@ digital_make_constellation_receiver_cb (digital_constellation_sptr constellation * */ -class digital_constellation_receiver_cb : public gr_block +class digital_constellation_receiver_cb : public gr_block, public gri_control_loop { public: int general_work (int noutput_items, @@ -71,126 +72,6 @@ class digital_constellation_receiver_cb : public gr_block gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); - - /******************************************************************* - 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 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: /*! @@ -213,15 +94,6 @@ protected: private: unsigned int d_M; - // Members related to carrier and phase tracking - 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; -- cgit