mirror of
https://github.com/hb9fxq/gr-digitalhf
synced 2024-12-22 15:10:00 +00:00
recentering of filter taps
This commit is contained in:
parent
ec9ce59cb3
commit
3fdf3ffa63
|
@ -158,6 +158,9 @@ if(NOT CPPUNIT_FOUND)
|
||||||
message(FATAL_ERROR "CppUnit required to compile digitalhf")
|
message(FATAL_ERROR "CppUnit required to compile digitalhf")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
include(GrMiscUtils)
|
||||||
|
GR_LOGGING()
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# Setup doxygen option
|
# Setup doxygen option
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
|
@ -317,7 +317,7 @@
|
||||||
</param>
|
</param>
|
||||||
<param>
|
<param>
|
||||||
<key>value</key>
|
<key>value</key>
|
||||||
<value>0.002</value>
|
<value>0.001</value>
|
||||||
</param>
|
</param>
|
||||||
<param>
|
<param>
|
||||||
<key>_enabled</key>
|
<key>_enabled</key>
|
||||||
|
@ -353,15 +353,15 @@
|
||||||
</param>
|
</param>
|
||||||
<param>
|
<param>
|
||||||
<key>start</key>
|
<key>start</key>
|
||||||
<value>0</value>
|
<value>0.0001</value>
|
||||||
</param>
|
</param>
|
||||||
<param>
|
<param>
|
||||||
<key>step</key>
|
<key>step</key>
|
||||||
<value>0.001</value>
|
<value>0.0001</value>
|
||||||
</param>
|
</param>
|
||||||
<param>
|
<param>
|
||||||
<key>stop</key>
|
<key>stop</key>
|
||||||
<value>0.02</value>
|
<value>0.01</value>
|
||||||
</param>
|
</param>
|
||||||
<param>
|
<param>
|
||||||
<key>rangeType</key>
|
<key>rangeType</key>
|
||||||
|
@ -396,7 +396,7 @@
|
||||||
</param>
|
</param>
|
||||||
<param>
|
<param>
|
||||||
<key>value</key>
|
<key>value</key>
|
||||||
<value>15</value>
|
<value>9</value>
|
||||||
</param>
|
</param>
|
||||||
</block>
|
</block>
|
||||||
<block>
|
<block>
|
||||||
|
@ -423,7 +423,7 @@
|
||||||
</param>
|
</param>
|
||||||
<param>
|
<param>
|
||||||
<key>value</key>
|
<key>value</key>
|
||||||
<value>15</value>
|
<value>9</value>
|
||||||
</param>
|
</param>
|
||||||
</block>
|
</block>
|
||||||
<block>
|
<block>
|
||||||
|
@ -453,6 +453,49 @@
|
||||||
<value>4</value>
|
<value>4</value>
|
||||||
</param>
|
</param>
|
||||||
</block>
|
</block>
|
||||||
|
<block>
|
||||||
|
<key>variable_rrc_filter_taps</key>
|
||||||
|
<param>
|
||||||
|
<key>comment</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_enabled</key>
|
||||||
|
<value>True</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>alpha</key>
|
||||||
|
<value>0.25</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_coordinate</key>
|
||||||
|
<value>(469, 352)</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_rotation</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>gain</key>
|
||||||
|
<value>1.0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>id</key>
|
||||||
|
<value>rrc_taps</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>ntaps</key>
|
||||||
|
<value>11*sps</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>samp_rate</key>
|
||||||
|
<value>samp_rate</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>sym_rate</key>
|
||||||
|
<value>samp_rate/sps</value>
|
||||||
|
</param>
|
||||||
|
</block>
|
||||||
<block>
|
<block>
|
||||||
<key>variable</key>
|
<key>variable</key>
|
||||||
<param>
|
<param>
|
||||||
|
@ -477,7 +520,7 @@
|
||||||
</param>
|
</param>
|
||||||
<param>
|
<param>
|
||||||
<key>value</key>
|
<key>value</key>
|
||||||
<value>12000</value>
|
<value>12001</value>
|
||||||
</param>
|
</param>
|
||||||
</block>
|
</block>
|
||||||
<block>
|
<block>
|
||||||
|
@ -774,7 +817,7 @@
|
||||||
</param>
|
</param>
|
||||||
<param>
|
<param>
|
||||||
<key>file</key>
|
<key>file</key>
|
||||||
<value>/Users/chm/Downloads/julusdalen.proxy.kiwisdr.com_2018-10-28T17_36_28Z_4644.80_iq.wav</value>
|
<value>/Users/chm/Downloads/kiwi-sm2gct.mooo.com_2018-10-30T10_35_39Z_8700.00_iq.wav</value>
|
||||||
</param>
|
</param>
|
||||||
<param>
|
<param>
|
||||||
<key>_coordinate</key>
|
<key>_coordinate</key>
|
||||||
|
@ -876,6 +919,112 @@
|
||||||
<value>STANAG_4285</value>
|
<value>STANAG_4285</value>
|
||||||
</param>
|
</param>
|
||||||
</block>
|
</block>
|
||||||
|
<block>
|
||||||
|
<key>fir_filter_xxx</key>
|
||||||
|
<param>
|
||||||
|
<key>alias</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>comment</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>affinity</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>decim</key>
|
||||||
|
<value>1</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_enabled</key>
|
||||||
|
<value>True</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_coordinate</key>
|
||||||
|
<value>(330, 293)</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_rotation</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>id</key>
|
||||||
|
<value>fir_filter_xxx_0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>maxoutbuf</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>minoutbuf</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>samp_delay</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>taps</key>
|
||||||
|
<value>rrc_taps</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>type</key>
|
||||||
|
<value>ccc</value>
|
||||||
|
</param>
|
||||||
|
</block>
|
||||||
|
<block>
|
||||||
|
<key>fractional_resampler_xx</key>
|
||||||
|
<param>
|
||||||
|
<key>alias</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>comment</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>affinity</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_enabled</key>
|
||||||
|
<value>1</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_coordinate</key>
|
||||||
|
<value>(96, 293)</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_rotation</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>id</key>
|
||||||
|
<value>fractional_resampler_xx_0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>maxoutbuf</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>minoutbuf</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>phase_shift</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>resamp_ratio</key>
|
||||||
|
<value>12001./11999.*0+1</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>type</key>
|
||||||
|
<value>complex</value>
|
||||||
|
</param>
|
||||||
|
</block>
|
||||||
<block>
|
<block>
|
||||||
<key>import</key>
|
<key>import</key>
|
||||||
<param>
|
<param>
|
||||||
|
@ -2315,13 +2464,13 @@
|
||||||
</connection>
|
</connection>
|
||||||
<connection>
|
<connection>
|
||||||
<source_block_id>blocks_multiply_const_vxx_0</source_block_id>
|
<source_block_id>blocks_multiply_const_vxx_0</source_block_id>
|
||||||
<sink_block_id>blocks_throttle_0</sink_block_id>
|
<sink_block_id>fractional_resampler_xx_0</sink_block_id>
|
||||||
<source_key>0</source_key>
|
<source_key>0</source_key>
|
||||||
<sink_key>0</sink_key>
|
<sink_key>0</sink_key>
|
||||||
</connection>
|
</connection>
|
||||||
<connection>
|
<connection>
|
||||||
<source_block_id>blocks_throttle_0</source_block_id>
|
<source_block_id>blocks_throttle_0</source_block_id>
|
||||||
<sink_block_id>preamble</sink_block_id>
|
<sink_block_id>fir_filter_xxx_0</sink_block_id>
|
||||||
<source_key>0</source_key>
|
<source_key>0</source_key>
|
||||||
<sink_key>0</sink_key>
|
<sink_key>0</sink_key>
|
||||||
</connection>
|
</connection>
|
||||||
|
@ -2349,6 +2498,18 @@
|
||||||
<source_key>soft_dec</source_key>
|
<source_key>soft_dec</source_key>
|
||||||
<sink_key>in</sink_key>
|
<sink_key>in</sink_key>
|
||||||
</connection>
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<source_block_id>fir_filter_xxx_0</source_block_id>
|
||||||
|
<sink_block_id>preamble</sink_block_id>
|
||||||
|
<source_key>0</source_key>
|
||||||
|
<sink_key>0</sink_key>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<source_block_id>fractional_resampler_xx_0</source_block_id>
|
||||||
|
<sink_block_id>blocks_throttle_0</sink_block_id>
|
||||||
|
<source_key>0</source_key>
|
||||||
|
<sink_key>0</sink_key>
|
||||||
|
</connection>
|
||||||
<connection>
|
<connection>
|
||||||
<source_block_id>preamble</source_block_id>
|
<source_block_id>preamble</source_block_id>
|
||||||
<sink_block_id>blocks_complex_to_mag_0</sink_block_id>
|
<sink_block_id>blocks_complex_to_mag_0</sink_block_id>
|
||||||
|
|
|
@ -22,9 +22,14 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <gnuradio/io_signature.h>
|
#include <boost/format.hpp>
|
||||||
|
|
||||||
#include <gnuradio/expj.h>
|
#include <gnuradio/expj.h>
|
||||||
|
#include <gnuradio/io_signature.h>
|
||||||
|
#include <gnuradio/logger.h>
|
||||||
|
|
||||||
#include <volk/volk.h>
|
#include <volk/volk.h>
|
||||||
|
|
||||||
#include "adaptive_dfe_impl.h"
|
#include "adaptive_dfe_impl.h"
|
||||||
|
|
||||||
#define VOLK_SAFE_DELETE(x) \
|
#define VOLK_SAFE_DELETE(x) \
|
||||||
|
@ -96,6 +101,8 @@ adaptive_dfe_impl::adaptive_dfe_impl(int sps, // samples per symbol
|
||||||
, _hist_symbols(nullptr)
|
, _hist_symbols(nullptr)
|
||||||
, _hist_sample_index(0)
|
, _hist_sample_index(0)
|
||||||
, _hist_symbol_index(0)
|
, _hist_symbol_index(0)
|
||||||
|
, _ignore_filter_updates(0)
|
||||||
|
, _saved_samples()
|
||||||
, _sample_counter(0)
|
, _sample_counter(0)
|
||||||
, _constellations()
|
, _constellations()
|
||||||
, _npwr()
|
, _npwr()
|
||||||
|
@ -118,6 +125,8 @@ adaptive_dfe_impl::adaptive_dfe_impl(int sps, // samples per symbol
|
||||||
, _ud(0)
|
, _ud(0)
|
||||||
, _state(WAIT_FOR_PREAMBLE)
|
, _state(WAIT_FOR_PREAMBLE)
|
||||||
{
|
{
|
||||||
|
GR_LOG_DECLARE_LOGPTR(d_logger);
|
||||||
|
GR_LOG_ASSIGN_LOGPTR(d_logger, "adaptive_dfe");
|
||||||
message_port_register_out(_msg_port_name);
|
message_port_register_out(_msg_port_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,11 +161,11 @@ adaptive_dfe_impl::general_work(int noutput_items,
|
||||||
|
|
||||||
int nout = 0;
|
int nout = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (; i<ninput_items[0] && nout < noutput_items; ++i) {
|
for (; i<ninput_items[0] && nout < noutput_items;) {
|
||||||
assert(nout < noutput_items);
|
assert(nout < noutput_items);
|
||||||
|
|
||||||
if (_state == WAIT_FOR_PREAMBLE) {
|
if (_state == WAIT_FOR_PREAMBLE) {
|
||||||
insert_sample(in[i]);
|
insert_sample(in[i++]);
|
||||||
uint64_t offset = 0;
|
uint64_t offset = 0;
|
||||||
float phase_est = 0;
|
float phase_est = 0;
|
||||||
if (get_correlation_tag(i, offset, phase_est)) {
|
if (get_correlation_tag(i, offset, phase_est)) {
|
||||||
|
@ -168,12 +177,14 @@ adaptive_dfe_impl::general_work(int noutput_items,
|
||||||
_descrambled_symbols.clear();
|
_descrambled_symbols.clear();
|
||||||
// _hist_sample_index = 0;
|
// _hist_sample_index = 0;
|
||||||
_hist_symbol_index = 0;
|
_hist_symbol_index = 0;
|
||||||
|
_ignore_filter_updates = 0;
|
||||||
|
_saved_samples.clear();
|
||||||
std::fill_n(_hist_symbols, 2*_nW, gr_complex(0));
|
std::fill_n(_hist_symbols, 2*_nW, gr_complex(0));
|
||||||
std::fill_n(_taps_samples, _nB+_nF+1, gr_complex(0));
|
std::fill_n(_taps_samples, _nB+_nF+1, gr_complex(0));
|
||||||
std::fill_n(_taps_symbols, _nW, gr_complex(0));
|
std::fill_n(_taps_symbols, _nW, gr_complex(0));
|
||||||
_samples.clear();
|
_samples.clear();
|
||||||
_phase = -phase_est;
|
_phase = -phase_est;
|
||||||
_taps_samples[_nB+1] = 1;
|
_taps_samples[_nB+1] = 0.01;
|
||||||
_taps_symbols[0] = 1;
|
_taps_symbols[0] = 1;
|
||||||
GILLock gil_lock;
|
GILLock gil_lock;
|
||||||
try {
|
try {
|
||||||
|
@ -224,11 +235,11 @@ adaptive_dfe_impl::general_work(int noutput_items,
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
_samples.push_back(in[i]);
|
_samples.push_back(in[i++]);
|
||||||
} // INITIAL_DOPPLER_ESTIMATE_CONTINUE
|
} // INITIAL_DOPPLER_ESTIMATE_CONTINUE
|
||||||
|
|
||||||
if (_state == INITIAL_DOPPLER_ESTIMATE_CONTINUE) {
|
if (_state == INITIAL_DOPPLER_ESTIMATE_CONTINUE) {
|
||||||
std::cout << "INITIAL_DOPPLER_ESTIMATE_CONTINUE\n";
|
GR_LOG_DEBUG(d_logger, "INITIAL_DOPPLER_ESTIMATE_CONTINUE");
|
||||||
while (!_samples.empty() && nout < noutput_items) {
|
while (!_samples.empty() && nout < noutput_items) {
|
||||||
insert_sample(_samples.back());
|
insert_sample(_samples.back());
|
||||||
_sample_counter += 1;
|
_sample_counter += 1;
|
||||||
|
@ -246,13 +257,15 @@ adaptive_dfe_impl::general_work(int noutput_items,
|
||||||
|
|
||||||
if (_state == DO_FILTER) {
|
if (_state == DO_FILTER) {
|
||||||
if ((_sample_counter%_sps) == 0) {
|
if ((_sample_counter%_sps) == 0) {
|
||||||
if (_symbol_counter == _symbols.size()) {
|
if (_symbol_counter == _symbols.size()) { // frame is ready
|
||||||
_symbol_counter = 0;
|
_symbol_counter = 0;
|
||||||
GILLock gil_lock;
|
GILLock gil_lock;
|
||||||
try {
|
try {
|
||||||
|
// update doppler estimate
|
||||||
update_doppler_information(_physicalLayer.attr("get_doppler")
|
update_doppler_information(_physicalLayer.attr("get_doppler")
|
||||||
(complex_vector_to_ndarray(_descrambled_symbols),
|
(complex_vector_to_ndarray(_descrambled_symbols),
|
||||||
complex_vector_to_ndarray(_samples)));
|
complex_vector_to_ndarray(_samples)));
|
||||||
|
// publish soft decisions
|
||||||
if (!_vec_soft_decisions.empty()) {
|
if (!_vec_soft_decisions.empty()) {
|
||||||
unsigned int const bits_per_symbol = _constellations[_constellation_index]->bits_per_symbol();
|
unsigned int const bits_per_symbol = _constellations[_constellation_index]->bits_per_symbol();
|
||||||
_msg_metadata = pmt::dict_add(_msg_metadata, pmt::mp("bits_per_symbol"), pmt::from_long(bits_per_symbol));
|
_msg_metadata = pmt::dict_add(_msg_metadata, pmt::mp("bits_per_symbol"), pmt::from_long(bits_per_symbol));
|
||||||
|
@ -262,16 +275,31 @@ adaptive_dfe_impl::general_work(int noutput_items,
|
||||||
_vec_soft_decisions.clear();
|
_vec_soft_decisions.clear();
|
||||||
}
|
}
|
||||||
_samples.clear();
|
_samples.clear();
|
||||||
|
// get information about the following frame
|
||||||
update_frame_information(_physicalLayer.attr("get_frame")());
|
update_frame_information(_physicalLayer.attr("get_frame")());
|
||||||
} catch (boost::python::error_already_set const&) {
|
} catch (boost::python::error_already_set const&) {
|
||||||
PyErr_Print();
|
PyErr_Print();
|
||||||
}
|
}
|
||||||
}
|
} // frame is ready
|
||||||
|
if (_ignore_filter_updates == 0) {
|
||||||
out[nout++] = filter();
|
out[nout++] = filter();
|
||||||
|
if (_symbol_counter+1 == _symbols.size())
|
||||||
|
recenter_filter_taps();
|
||||||
|
} else {
|
||||||
|
_ignore_filter_updates -= 1;
|
||||||
}
|
}
|
||||||
insert_sample(in[i]);
|
} // (_sample_counter%_sps) == 0
|
||||||
if (_need_samples)
|
|
||||||
|
|
||||||
|
if (_need_samples) {
|
||||||
_samples.push_back(_hist_samples[_hist_sample_index+_nB+1]);
|
_samples.push_back(_hist_samples[_hist_sample_index+_nB+1]);
|
||||||
|
}
|
||||||
|
if (_saved_samples.empty()) {
|
||||||
|
insert_sample(in[i++]);
|
||||||
|
} else {
|
||||||
|
insert_sample(_saved_samples.back());
|
||||||
|
_saved_samples.pop_back();
|
||||||
|
}
|
||||||
_sample_counter += 1;
|
_sample_counter += 1;
|
||||||
} // DO_FILTER
|
} // DO_FILTER
|
||||||
} // next input sample
|
} // next input sample
|
||||||
|
@ -306,10 +334,11 @@ bool adaptive_dfe_impl::start()
|
||||||
std::fill_n(_taps_samples, (_nB+_nF+1), gr_complex(0));
|
std::fill_n(_taps_samples, (_nB+_nF+1), gr_complex(0));
|
||||||
std::fill_n(_taps_symbols, _nW, gr_complex(0));
|
std::fill_n(_taps_symbols, _nW, gr_complex(0));
|
||||||
|
|
||||||
_taps_samples[_nB+1] = 1;
|
_taps_samples[_nB+1] = 0.01;
|
||||||
_taps_symbols[0] = 1;
|
_taps_symbols[0] = 1;
|
||||||
|
|
||||||
std::cout << "adaptive_dfe_impl::start() " << _nB << " " << _nF << " " << _mu << " " << _alpha << std::endl;
|
GR_LOG_DEBUG(d_logger,str(boost::format("adaptive_dfe_impl::start() nB=%d nF=%d mu=%f alpha=%f")
|
||||||
|
% _nB % _nF % _mu % _alpha));
|
||||||
GILLock gil_lock;
|
GILLock gil_lock;
|
||||||
try {
|
try {
|
||||||
boost::python::object module = boost::python::import(boost::python::str("digitalhf.physical_layer." + _py_module_name));
|
boost::python::object module = boost::python::import(boost::python::str("digitalhf.physical_layer." + _py_module_name));
|
||||||
|
@ -325,7 +354,7 @@ bool adaptive_dfe_impl::start()
|
||||||
bool adaptive_dfe_impl::stop()
|
bool adaptive_dfe_impl::stop()
|
||||||
{
|
{
|
||||||
gr::thread::scoped_lock lock(d_setlock);
|
gr::thread::scoped_lock lock(d_setlock);
|
||||||
std::cout << "adaptive_dfe_impl::stop()" << std::endl;
|
GR_LOG_DEBUG(d_logger, "adaptive_dfe_impl::stop()");
|
||||||
GILLock gil_lock;
|
GILLock gil_lock;
|
||||||
_physicalLayer = boost::python::object();
|
_physicalLayer = boost::python::object();
|
||||||
VOLK_SAFE_DELETE(_taps_samples);
|
VOLK_SAFE_DELETE(_taps_samples);
|
||||||
|
@ -334,6 +363,7 @@ bool adaptive_dfe_impl::stop()
|
||||||
VOLK_SAFE_DELETE(_hist_symbols);
|
VOLK_SAFE_DELETE(_hist_symbols);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
gr_complex adaptive_dfe_impl::filter() {
|
gr_complex adaptive_dfe_impl::filter() {
|
||||||
gr_complex filter_output = 0;
|
gr_complex filter_output = 0;
|
||||||
volk_32fc_x2_dot_prod_32fc(&filter_output,
|
volk_32fc_x2_dot_prod_32fc(&filter_output,
|
||||||
|
@ -371,17 +401,10 @@ gr_complex adaptive_dfe_impl::filter() {
|
||||||
known_symbol = _scramble[_symbol_counter] * descrambled_symbol;
|
known_symbol = _scramble[_symbol_counter] * descrambled_symbol;
|
||||||
}
|
}
|
||||||
gr_complex err = filter_output - known_symbol;
|
gr_complex err = filter_output - known_symbol;
|
||||||
int jMax=0;
|
|
||||||
float tMax=0;
|
|
||||||
for (int j=0; j<_nB+_nF+1; ++j) {
|
for (int j=0; j<_nB+_nF+1; ++j) {
|
||||||
assert(_hist_sample_index+j < 2*(_nB+_nF+1));
|
assert(_hist_sample_index+j < 2*(_nB+_nF+1));
|
||||||
_taps_samples[j] -= _mu*err*std::conj(_hist_samples[_hist_sample_index+j]);
|
_taps_samples[j] -= _mu*err*std::conj(_hist_samples[_hist_sample_index+j]);
|
||||||
// if (std::abs(_taps_samples[j]) > tMax) {
|
|
||||||
// tMax = std::abs(_taps_samples[j]);
|
|
||||||
// jMax = j;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
// std::cout << "taps_max: " << jMax << " " << tMax << std::endl;
|
|
||||||
for (int j=0; j<_nW; ++j) {
|
for (int j=0; j<_nW; ++j) {
|
||||||
assert(_hist_symbol_index+j < 2*_nW);
|
assert(_hist_symbol_index+j < 2*_nW);
|
||||||
_taps_symbols[j] -= _mu*err*std::conj(_hist_symbols[_hist_symbol_index+j]) + _alpha*_taps_symbols[j];
|
_taps_symbols[j] -= _mu*err*std::conj(_hist_symbols[_hist_symbol_index+j]) + _alpha*_taps_symbols[j];
|
||||||
|
@ -397,9 +420,49 @@ gr_complex adaptive_dfe_impl::filter() {
|
||||||
return filter_output*std::conj(_scramble[_symbol_counter++]);
|
return filter_output*std::conj(_scramble[_symbol_counter++]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void adaptive_dfe_impl::recenter_filter_taps() {
|
||||||
|
// get max(abs(taps))
|
||||||
|
ssize_t const idx_max = std::distance(_taps_samples,
|
||||||
|
std::max_element(_taps_samples+_nB+1-3*_sps, _taps_samples+_nB+1+3*_sps,
|
||||||
|
[](gr_complex a, gr_complex b) {
|
||||||
|
return std::norm(a) < std::norm(b);
|
||||||
|
}));
|
||||||
|
GR_LOG_DEBUG(d_logger, str(boost::format("idx_max=%2d abs(tap_max)=%f") % idx_max % std::abs(_taps_samples[idx_max])));
|
||||||
|
|
||||||
|
if (idx_max-_nB-1 >= 2*_sps && _saved_samples.empty() && _ignore_filter_updates==0) {
|
||||||
|
// maximum is right of the center tap
|
||||||
|
// -> shift taps to the left left
|
||||||
|
GR_LOG_DEBUG(d_logger, "shift left");
|
||||||
|
std::copy(_taps_samples+2*_sps, _taps_samples+_nB+_nF+1, _taps_samples);
|
||||||
|
std::fill_n(_taps_samples+_nB+_nF+1-2*_sps, 2*_sps, gr_complex(0));
|
||||||
|
// and omit the next two calls to filter in order to keep the alignment between samples and taps
|
||||||
|
_ignore_filter_updates = 2;
|
||||||
|
|
||||||
|
} else if (idx_max-_nB-1 <= -2*_sps && _saved_samples.empty() && _ignore_filter_updates==0) {
|
||||||
|
// maximum is left of the center tap
|
||||||
|
// -> shift taps to the right
|
||||||
|
GR_LOG_DEBUG(d_logger, "shift right");
|
||||||
|
std::copy_backward(_taps_samples, _taps_samples+_nB+_nF+1-2*_sps,
|
||||||
|
_taps_samples+_nB+_nF+1);
|
||||||
|
std::fill_n(_taps_samples, 2*_sps, gr_complex(0));
|
||||||
|
// save the last 2*_sps samples (will be reinserted)
|
||||||
|
_saved_samples.resize(2*_sps);
|
||||||
|
std::reverse_copy(_hist_samples+_hist_sample_index+(_nB+_nF+1)-2*_sps,
|
||||||
|
_hist_samples+_hist_sample_index+(_nB+_nF+1),
|
||||||
|
_saved_samples.begin());
|
||||||
|
// shift samples index
|
||||||
|
_hist_sample_index += (_nB+_nF+1)-2*_sps;
|
||||||
|
_hist_sample_index %= (_nB+_nF+1);
|
||||||
|
// set the 1st 2*_sps unknown old samples to zero
|
||||||
|
for (int l=_hist_sample_index; l<_hist_sample_index+2*_sps; ++l) {
|
||||||
|
int const k = (l+_nB+_nF+1)%(2*(_nB+_nF+1));
|
||||||
|
_hist_samples[l] = _hist_samples[k] = gr_complex(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
void adaptive_dfe_impl::set_mode(std::string mode) {
|
void adaptive_dfe_impl::set_mode(std::string mode) {
|
||||||
gr::thread::scoped_lock lock(d_setlock);
|
gr::thread::scoped_lock lock(d_setlock);
|
||||||
std::cout << "adaptive_dfe_impl::set_mode " << mode << std::endl;
|
GR_LOG_DEBUG(d_logger, "adaptive_dfe_impl::set_mode "+ mode);
|
||||||
GILLock gil_lock;
|
GILLock gil_lock;
|
||||||
try {
|
try {
|
||||||
_physicalLayer.attr("set_mode")(mode);
|
_physicalLayer.attr("set_mode")(mode);
|
||||||
|
@ -483,13 +546,14 @@ void adaptive_dfe_impl::update_pll(float doppler) {
|
||||||
_ud = delta_f;
|
_ud = delta_f;
|
||||||
_df +=_b[0]*_ud + _b[1]*ud_old;
|
_df +=_b[0]*_ud + _b[1]*ud_old;
|
||||||
}
|
}
|
||||||
std::cout << "PLL: " << _df << " " << delta_f << std::endl;
|
GR_LOG_DEBUG(d_logger, str(boost::format("PLL: df=%f delta_f=%f (rad/symb)") % _df % delta_f));
|
||||||
}
|
}
|
||||||
void adaptive_dfe_impl::insert_sample(gr_complex z) {
|
void adaptive_dfe_impl::insert_sample(gr_complex z) {
|
||||||
// insert sample into the circular buffer
|
// insert sample into the circular buffer
|
||||||
_hist_samples[_hist_sample_index] = _hist_samples[_hist_sample_index+_nB+_nF+1] = z * gr_expj(-_phase);
|
_hist_samples[_hist_sample_index] = _hist_samples[_hist_sample_index+_nB+_nF+1] = z * gr_expj(-_phase);
|
||||||
if (++_hist_sample_index == _nB+_nF+1)
|
if (++_hist_sample_index == _nB+_nF+1)
|
||||||
_hist_sample_index = 0;
|
_hist_sample_index = 0;
|
||||||
|
if (z != gr_complex(0))
|
||||||
update_local_oscillator();
|
update_local_oscillator();
|
||||||
}
|
}
|
||||||
void adaptive_dfe_impl:: update_local_oscillator() {
|
void adaptive_dfe_impl:: update_local_oscillator() {
|
||||||
|
@ -503,7 +567,7 @@ bool adaptive_dfe_impl::get_correlation_tag(uint64_t i, uint64_t& offset, float&
|
||||||
std::vector<tag_t> v;
|
std::vector<tag_t> v;
|
||||||
get_tags_in_window(v, 0, i,i+1);
|
get_tags_in_window(v, 0, i,i+1);
|
||||||
for (int j=0; j<v.size(); ++j) {
|
for (int j=0; j<v.size(); ++j) {
|
||||||
std::cout << "tag " << v[j].key << " " << v[j].offset-nitems_read(0) << std::endl;
|
std::cout << "tag " << v[j].key << " " << v[j].offset-nitems_read(0) << " " << v[j].value << std::endl;
|
||||||
if (v[j].key == pmt::mp("phase_est")) {
|
if (v[j].key == pmt::mp("phase_est")) {
|
||||||
phase_est = pmt::to_double(v[j].value);
|
phase_est = pmt::to_double(v[j].value);
|
||||||
std::cout << "phase_est " << v[j].offset <<" " << nitems_read(0) << " " << phase_est << std::endl;
|
std::cout << "phase_est " << v[j].offset <<" " << nitems_read(0) << " " << phase_est << std::endl;
|
||||||
|
|
|
@ -50,7 +50,10 @@ private:
|
||||||
int _hist_sample_index;
|
int _hist_sample_index;
|
||||||
int _hist_symbol_index;
|
int _hist_symbol_index;
|
||||||
|
|
||||||
std::size_t _sample_counter;
|
int _ignore_filter_updates;
|
||||||
|
std::vector<gr_complex> _saved_samples;
|
||||||
|
|
||||||
|
uint64_t _sample_counter;
|
||||||
|
|
||||||
std::vector<gr::digital::constellation_sptr> _constellations;
|
std::vector<gr::digital::constellation_sptr> _constellations;
|
||||||
std::vector<float> _npwr;
|
std::vector<float> _npwr;
|
||||||
|
@ -88,6 +91,7 @@ private:
|
||||||
|
|
||||||
void update_local_oscillator();
|
void update_local_oscillator();
|
||||||
gr_complex filter();
|
gr_complex filter();
|
||||||
|
void recenter_filter_taps();
|
||||||
|
|
||||||
void insert_sample(gr_complex z);
|
void insert_sample(gr_complex z);
|
||||||
void update_pll(float doppler);
|
void update_pll(float doppler);
|
||||||
|
|
|
@ -68,12 +68,14 @@ class PhysicalLayer(object):
|
||||||
if len(symbols) != 0:
|
if len(symbols) != 0:
|
||||||
idx = range(30,80) if self._is_first_frame else range(80)
|
idx = range(30,80) if self._is_first_frame else range(80)
|
||||||
z = symbols[idx]*np.conj(self._preamble['symb'][idx])
|
z = symbols[idx]*np.conj(self._preamble['symb'][idx])
|
||||||
|
print('quality_preamble',np.sum(np.real(z)<0))
|
||||||
success = np.sum(np.real(z)<0) < 30
|
success = np.sum(np.real(z)<0) < 30
|
||||||
return success,doppler
|
return success,doppler
|
||||||
|
|
||||||
def quality_data(self, s):
|
def quality_data(self, s):
|
||||||
"""quality check for the data frame"""
|
"""quality check for the data frame"""
|
||||||
known_symbols = np.mod(range(176),48)>=32
|
known_symbols = np.mod(range(176),48)>=32
|
||||||
|
print('quality_data',np.sum(np.real(s[known_symbols])<0))
|
||||||
success = np.sum(np.real(s[known_symbols])<0) < 20
|
success = np.sum(np.real(s[known_symbols])<0) < 20
|
||||||
return success,0 ## no doppler estimate for data frames
|
return success,0 ## no doppler estimate for data frames
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue