summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gr-digital/lib/digital_constellation_receiver_cb.cc145
-rw-r--r--gr-digital/lib/digital_constellation_receiver_cb.h132
2 files changed, 9 insertions, 268 deletions
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 <gr_block.h>
#include <digital_constellation.h>
+#include <gri_control_loop.h>
#include <gr_complex.h>
#include <math.h>
#include <fstream>
@@ -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;