summaryrefslogtreecommitdiff
path: root/gr-digital/lib
diff options
context:
space:
mode:
Diffstat (limited to 'gr-digital/lib')
-rw-r--r--gr-digital/lib/digital_constellation_receiver_cb.cc135
-rw-r--r--gr-digital/lib/digital_constellation_receiver_cb.h156
-rw-r--r--gr-digital/lib/digital_costas_loop_cc.cc1
-rw-r--r--gr-digital/lib/digital_costas_loop_cc.h7
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