1
0
Fork 0
mirror of https://github.com/hb9fxq/gr-digitalhf synced 2024-12-22 15:10:00 +00:00

message port with soft decisions added

This commit is contained in:
cmayer 2018-10-29 16:07:20 +01:00
parent 4c94787579
commit 50176e7ed7
5 changed files with 427 additions and 26 deletions

View file

@ -226,11 +226,11 @@
</param> </param>
<param> <param>
<key>_coordinate</key> <key>_coordinate</key>
<value>(42, 384)</value> <value>(1152, 490)</value>
</param> </param>
<param> <param>
<key>gui_hint</key> <key>gui_hint</key>
<value></value> <value>(4,0,1,1)</value>
</param> </param>
<param> <param>
<key>_rotation</key> <key>_rotation</key>
@ -774,11 +774,11 @@
</param> </param>
<param> <param>
<key>file</key> <key>file</key>
<value>/Users/chm/Software/signal-analysis/gnuradio/20181027T095433Z_6407800_SM2GCT_iq.wav</value> <value>/Users/chm/Downloads/julusdalen.proxy.kiwisdr.com_2018-10-28T17_36_28Z_4644.80_iq.wav</value>
</param> </param>
<param> <param>
<key>_coordinate</key> <key>_coordinate</key>
<value>(32, 154)</value> <value>(10, 154)</value>
</param> </param>
<param> <param>
<key>_rotation</key> <key>_rotation</key>
@ -802,7 +802,7 @@
</param> </param>
<param> <param>
<key>repeat</key> <key>repeat</key>
<value>True</value> <value>False</value>
</param> </param>
</block> </block>
<block> <block>
@ -825,7 +825,7 @@
</param> </param>
<param> <param>
<key>_coordinate</key> <key>_coordinate</key>
<value>(874, 458)</value> <value>(874, 389)</value>
</param> </param>
<param> <param>
<key>_rotation</key> <key>_rotation</key>
@ -1025,11 +1025,11 @@
</param> </param>
<param> <param>
<key>_coordinate</key> <key>_coordinate</key>
<value>(1120, 496)</value> <value>(1109, 410)</value>
</param> </param>
<param> <param>
<key>gui_hint</key> <key>gui_hint</key>
<value>(2,2,2,2)</value> <value>(2,2,3,2)</value>
</param> </param>
<param> <param>
<key>_rotation</key> <key>_rotation</key>
@ -1652,7 +1652,7 @@
</param> </param>
<param> <param>
<key>size</key> <key>size</key>
<value>1024</value> <value>1024/2</value>
</param> </param>
<param> <param>
<key>srate</key> <key>srate</key>
@ -1668,7 +1668,7 @@
</param> </param>
<param> <param>
<key>tr_delay</key> <key>tr_delay</key>
<value>0.02</value> <value>0.01</value>
</param> </param>
<param> <param>
<key>tr_level</key> <key>tr_level</key>
@ -1711,6 +1711,373 @@
<value>0</value> <value>0</value>
</param> </param>
</block> </block>
<block>
<key>qtgui_time_sink_x</key>
<param>
<key>autoscale</key>
<value>False</value>
</param>
<param>
<key>axislabels</key>
<value>True</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>ctrlpanel</key>
<value>False</value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>entags</key>
<value>True</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(1002, 602)</value>
</param>
<param>
<key>gui_hint</key>
<value>(5,0,1,4)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid</key>
<value>False</value>
</param>
<param>
<key>id</key>
<value>qtgui_time_sink_x_1</value>
</param>
<param>
<key>legend</key>
<value>False</value>
</param>
<param>
<key>alpha1</key>
<value>1.0</value>
</param>
<param>
<key>color1</key>
<value>"blue"</value>
</param>
<param>
<key>label1</key>
<value></value>
</param>
<param>
<key>marker1</key>
<value>-1</value>
</param>
<param>
<key>style1</key>
<value>1</value>
</param>
<param>
<key>width1</key>
<value>1</value>
</param>
<param>
<key>alpha10</key>
<value>1.0</value>
</param>
<param>
<key>color10</key>
<value>"blue"</value>
</param>
<param>
<key>label10</key>
<value></value>
</param>
<param>
<key>marker10</key>
<value>-1</value>
</param>
<param>
<key>style10</key>
<value>1</value>
</param>
<param>
<key>width10</key>
<value>1</value>
</param>
<param>
<key>alpha2</key>
<value>1.0</value>
</param>
<param>
<key>color2</key>
<value>"red"</value>
</param>
<param>
<key>label2</key>
<value></value>
</param>
<param>
<key>marker2</key>
<value>-1</value>
</param>
<param>
<key>style2</key>
<value>1</value>
</param>
<param>
<key>width2</key>
<value>1</value>
</param>
<param>
<key>alpha3</key>
<value>1.0</value>
</param>
<param>
<key>color3</key>
<value>"green"</value>
</param>
<param>
<key>label3</key>
<value></value>
</param>
<param>
<key>marker3</key>
<value>-1</value>
</param>
<param>
<key>style3</key>
<value>1</value>
</param>
<param>
<key>width3</key>
<value>1</value>
</param>
<param>
<key>alpha4</key>
<value>1.0</value>
</param>
<param>
<key>color4</key>
<value>"black"</value>
</param>
<param>
<key>label4</key>
<value></value>
</param>
<param>
<key>marker4</key>
<value>-1</value>
</param>
<param>
<key>style4</key>
<value>1</value>
</param>
<param>
<key>width4</key>
<value>1</value>
</param>
<param>
<key>alpha5</key>
<value>1.0</value>
</param>
<param>
<key>color5</key>
<value>"cyan"</value>
</param>
<param>
<key>label5</key>
<value></value>
</param>
<param>
<key>marker5</key>
<value>-1</value>
</param>
<param>
<key>style5</key>
<value>1</value>
</param>
<param>
<key>width5</key>
<value>1</value>
</param>
<param>
<key>alpha6</key>
<value>1.0</value>
</param>
<param>
<key>color6</key>
<value>"magenta"</value>
</param>
<param>
<key>label6</key>
<value></value>
</param>
<param>
<key>marker6</key>
<value>-1</value>
</param>
<param>
<key>style6</key>
<value>1</value>
</param>
<param>
<key>width6</key>
<value>1</value>
</param>
<param>
<key>alpha7</key>
<value>1.0</value>
</param>
<param>
<key>color7</key>
<value>"yellow"</value>
</param>
<param>
<key>label7</key>
<value></value>
</param>
<param>
<key>marker7</key>
<value>-1</value>
</param>
<param>
<key>style7</key>
<value>1</value>
</param>
<param>
<key>width7</key>
<value>1</value>
</param>
<param>
<key>alpha8</key>
<value>1.0</value>
</param>
<param>
<key>color8</key>
<value>"dark red"</value>
</param>
<param>
<key>label8</key>
<value></value>
</param>
<param>
<key>marker8</key>
<value>-1</value>
</param>
<param>
<key>style8</key>
<value>1</value>
</param>
<param>
<key>width8</key>
<value>1</value>
</param>
<param>
<key>alpha9</key>
<value>1.0</value>
</param>
<param>
<key>color9</key>
<value>"dark green"</value>
</param>
<param>
<key>label9</key>
<value></value>
</param>
<param>
<key>marker9</key>
<value>-1</value>
</param>
<param>
<key>style9</key>
<value>1</value>
</param>
<param>
<key>width9</key>
<value>1</value>
</param>
<param>
<key>name</key>
<value>""</value>
</param>
<param>
<key>nconnections</key>
<value>1</value>
</param>
<param>
<key>size</key>
<value>1024</value>
</param>
<param>
<key>srate</key>
<value>samp_rate/sps/2</value>
</param>
<param>
<key>stemplot</key>
<value>False</value>
</param>
<param>
<key>tr_chan</key>
<value>0</value>
</param>
<param>
<key>tr_delay</key>
<value>0</value>
</param>
<param>
<key>tr_level</key>
<value>0.0</value>
</param>
<param>
<key>tr_mode</key>
<value>qtgui.TRIG_MODE_AUTO</value>
</param>
<param>
<key>tr_slope</key>
<value>qtgui.TRIG_SLOPE_POS</value>
</param>
<param>
<key>tr_tag</key>
<value>"soft_dec"</value>
</param>
<param>
<key>type</key>
<value>msg_float</value>
</param>
<param>
<key>update_time</key>
<value>0.10</value>
</param>
<param>
<key>ylabel</key>
<value>soft_dec</value>
</param>
<param>
<key>yunit</key>
<value>""</value>
</param>
<param>
<key>ymax</key>
<value>7</value>
</param>
<param>
<key>ymin</key>
<value>-7</value>
</param>
</block>
<block> <block>
<key>qtgui_waterfall_sink_x</key> <key>qtgui_waterfall_sink_x</key>
<param> <param>
@ -1976,6 +2343,12 @@
<source_key>0</source_key> <source_key>0</source_key>
<sink_key>0</sink_key> <sink_key>0</sink_key>
</connection> </connection>
<connection>
<source_block_id>digitalhf_adaptive_dfe_0</source_block_id>
<sink_block_id>qtgui_time_sink_x_1</sink_block_id>
<source_key>soft_dec</source_key>
<sink_key>in</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>

View file

@ -73,4 +73,10 @@
<type>complex</type> <type>complex</type>
<!-- byte, short, xxx_vector --> <!-- byte, short, xxx_vector -->
</source> </source>
<source>
<name>soft_dec</name>
<type>message</type>
<optional>1</optional>
</source>
</block> </block>

View file

@ -28,7 +28,7 @@
#include "adaptive_dfe_impl.h" #include "adaptive_dfe_impl.h"
#define VOLK_SAFE_DELETE(x) \ #define VOLK_SAFE_DELETE(x) \
volk_free(x); \ volk_free(x); \
x = nullptr x = nullptr
namespace gr { namespace gr {
@ -108,12 +108,17 @@ adaptive_dfe_impl::adaptive_dfe_impl(int sps, // samples per symbol
, _descrambled_symbols() , _descrambled_symbols()
, _symbol_counter(0) , _symbol_counter(0)
, _need_samples(false) , _need_samples(false)
, _save_soft_decisions(false)
, _vec_soft_decisions()
, _msg_port_name(pmt::mp("soft_dec"))
, _msg_metadata(pmt::make_dict())
, _df(0) , _df(0)
, _phase(0) , _phase(0)
, _b{0.338187046465954, -0.288839024460507} , _b{0.338187046465954, -0.288839024460507}
, _ud(0) , _ud(0)
, _state(WAIT_FOR_PREAMBLE) , _state(WAIT_FOR_PREAMBLE)
{ {
message_port_register_out(_msg_port_name);
} }
/* /*
@ -121,6 +126,8 @@ adaptive_dfe_impl::adaptive_dfe_impl(int sps, // samples per symbol
*/ */
adaptive_dfe_impl::~adaptive_dfe_impl() adaptive_dfe_impl::~adaptive_dfe_impl()
{ {
_msg_port_name = pmt::PMT_NIL;
_msg_metadata = pmt::PMT_NIL;
VOLK_SAFE_DELETE(_taps_samples); VOLK_SAFE_DELETE(_taps_samples);
VOLK_SAFE_DELETE(_taps_symbols); VOLK_SAFE_DELETE(_taps_symbols);
VOLK_SAFE_DELETE(_hist_samples); VOLK_SAFE_DELETE(_hist_samples);
@ -246,6 +253,14 @@ adaptive_dfe_impl::general_work(int noutput_items,
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)));
if (!_vec_soft_decisions.empty()) {
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));
message_port_pub(_msg_port_name,
pmt::cons(_msg_metadata,
pmt::init_f32vector(_vec_soft_decisions.size(), _vec_soft_decisions)));
_vec_soft_decisions.clear();
}
_samples.clear(); _samples.clear();
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&) {
@ -340,18 +355,19 @@ gr_complex adaptive_dfe_impl::filter() {
gr_complex descrambled_symbol = 0; gr_complex descrambled_symbol = 0;
constell->map_to_points(jc, &descrambled_symbol); constell->map_to_points(jc, &descrambled_symbol);
// make soft decisions if (_save_soft_decisions) {
float const err = std::abs(descrambled_filter_output - descrambled_symbol); float const err = std::abs(descrambled_filter_output - descrambled_symbol);
_npwr_counter[_constellation_index] += (_npwr_counter[_constellation_index] < _npwr_max_time_constant); _npwr_counter[_constellation_index] += (_npwr_counter[_constellation_index] < _npwr_max_time_constant);
float const alpha = 1.0f/_npwr_counter[_constellation_index]; float const alpha = 1.0f/_npwr_counter[_constellation_index];
_npwr[_constellation_index] = (1-alpha)*_npwr[_constellation_index] + alpha*err; _npwr[_constellation_index] = (1-alpha)*_npwr[_constellation_index] + alpha*err;
std::vector<float> soft_dec = constell->calc_soft_dec(descrambled_filter_output, _npwr[_constellation_index]); std::vector<float> const soft_dec = constell->calc_soft_dec(descrambled_filter_output, _npwr[_constellation_index]);
// std::cout << "soft_dec " << _npwr[_constellation_index] << " : "; std::copy(soft_dec.begin(), soft_dec.end(), std::back_inserter<std::vector<float> >(_vec_soft_decisions));
// for (int k=0; k<soft_dec.size(); ++k) { // std::cout << "soft_dec " << _npwr[_constellation_index] << " : ";
// std::cout << soft_dec[k] << " "; // for (int k=0; k<soft_dec.size(); ++k) {
// } // std::cout << soft_dec[k] << " ";
// std::cout << "\n"; // }
// std::cout << "\n";
}
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;
@ -419,7 +435,7 @@ void adaptive_dfe_impl::update_constellations(boost::python::object obj)
bool adaptive_dfe_impl::update_frame_information(boost::python::object obj) bool adaptive_dfe_impl::update_frame_information(boost::python::object obj)
{ {
int const n = boost::python::extract<int>(obj.attr("__len__")()); int const n = boost::python::extract<int>(obj.attr("__len__")());
assert(n==3); assert(n==4);
boost::python::numpy::ndarray array = boost::python::numpy::array(obj[0]); boost::python::numpy::ndarray array = boost::python::numpy::array(obj[0]);
char const* data = array.get_data(); char const* data = array.get_data();
int const m = array.shape(0); int const m = array.shape(0);
@ -434,6 +450,7 @@ bool adaptive_dfe_impl::update_frame_information(boost::python::object obj)
} }
_constellation_index = boost::python::extract<int> (obj[1]); _constellation_index = boost::python::extract<int> (obj[1]);
_need_samples = boost::python::extract<bool>(obj[2]); _need_samples = boost::python::extract<bool>(obj[2]);
_save_soft_decisions = boost::python::extract<bool>(obj[3]);
return true; return true;
} }
bool adaptive_dfe_impl::update_doppler_information(boost::python::object obj) bool adaptive_dfe_impl::update_doppler_information(boost::python::object obj)

View file

@ -64,6 +64,10 @@ private:
int _symbol_counter; int _symbol_counter;
bool _need_samples; bool _need_samples;
bool _save_soft_decisions;
std::vector<float> _vec_soft_decisions;
pmt::pmt_t _msg_port_name;
pmt::pmt_t _msg_metadata;
// PLL for doppler tracking // PLL for doppler tracking
float _df; // frequency offset in radians per sample float _df; // frequency offset in radians per sample

View file

@ -34,9 +34,10 @@ class PhysicalLayer(object):
"""returns a tuple describing the frame: """returns a tuple describing the frame:
[0] ... known+unknown symbols and scrambling [0] ... known+unknown symbols and scrambling
[1] ... modulation type after descrambling [1] ... modulation type after descrambling
[2] ... a boolean indicating whethere or not raw IQ samples needed""" [2] ... a boolean indicating whethere or not raw IQ samples needed
[3] ... a boolean indicating if the soft decision for the unknown symbols are saved"""
print('-------------------- get_frame --------------------', self._frame_counter) print('-------------------- get_frame --------------------', self._frame_counter)
return [self._preamble,self.MODE_BPSK,True] if self.is_preamble() else [self._data,self._mode,False] return [self._preamble,self.MODE_BPSK,True,False] if self.is_preamble() else [self._data,self._mode,False,True]
def get_doppler(self, symbols, iq_samples): def get_doppler(self, symbols, iq_samples):
"""returns a tuple """returns a tuple