From 50176e7ed7ad47fb34199ecfff60bfb9d12d75c3 Mon Sep 17 00:00:00 2001 From: cmayer Date: Mon, 29 Oct 2018 16:07:20 +0100 Subject: [PATCH] message port with soft decisions added --- examples/test_cc.grc | 393 ++++++++++++++++++++++++++- grc/digitalhf_adaptive_dfe.xml | 6 + lib/adaptive_dfe_impl.cc | 45 ++- lib/adaptive_dfe_impl.h | 4 + python/physical_layer/STANAG_4285.py | 5 +- 5 files changed, 427 insertions(+), 26 deletions(-) diff --git a/examples/test_cc.grc b/examples/test_cc.grc index e9f4478..ca2a7e7 100644 --- a/examples/test_cc.grc +++ b/examples/test_cc.grc @@ -226,11 +226,11 @@ _coordinate - (42, 384) + (1152, 490) gui_hint - + (4,0,1,1) _rotation @@ -774,11 +774,11 @@ file - /Users/chm/Software/signal-analysis/gnuradio/20181027T095433Z_6407800_SM2GCT_iq.wav + /Users/chm/Downloads/julusdalen.proxy.kiwisdr.com_2018-10-28T17_36_28Z_4644.80_iq.wav _coordinate - (32, 154) + (10, 154) _rotation @@ -802,7 +802,7 @@ repeat - True + False @@ -825,7 +825,7 @@ _coordinate - (874, 458) + (874, 389) _rotation @@ -1025,11 +1025,11 @@ _coordinate - (1120, 496) + (1109, 410) gui_hint - (2,2,2,2) + (2,2,3,2) _rotation @@ -1652,7 +1652,7 @@ size - 1024 + 1024/2 srate @@ -1668,7 +1668,7 @@ tr_delay - 0.02 + 0.01 tr_level @@ -1711,6 +1711,373 @@ 0 + + qtgui_time_sink_x + + autoscale + False + + + axislabels + True + + + alias + + + + comment + + + + ctrlpanel + False + + + affinity + + + + entags + True + + + _enabled + True + + + _coordinate + (1002, 602) + + + gui_hint + (5,0,1,4) + + + _rotation + 0 + + + grid + False + + + id + qtgui_time_sink_x_1 + + + legend + False + + + alpha1 + 1.0 + + + color1 + "blue" + + + label1 + + + + marker1 + -1 + + + style1 + 1 + + + width1 + 1 + + + alpha10 + 1.0 + + + color10 + "blue" + + + label10 + + + + marker10 + -1 + + + style10 + 1 + + + width10 + 1 + + + alpha2 + 1.0 + + + color2 + "red" + + + label2 + + + + marker2 + -1 + + + style2 + 1 + + + width2 + 1 + + + alpha3 + 1.0 + + + color3 + "green" + + + label3 + + + + marker3 + -1 + + + style3 + 1 + + + width3 + 1 + + + alpha4 + 1.0 + + + color4 + "black" + + + label4 + + + + marker4 + -1 + + + style4 + 1 + + + width4 + 1 + + + alpha5 + 1.0 + + + color5 + "cyan" + + + label5 + + + + marker5 + -1 + + + style5 + 1 + + + width5 + 1 + + + alpha6 + 1.0 + + + color6 + "magenta" + + + label6 + + + + marker6 + -1 + + + style6 + 1 + + + width6 + 1 + + + alpha7 + 1.0 + + + color7 + "yellow" + + + label7 + + + + marker7 + -1 + + + style7 + 1 + + + width7 + 1 + + + alpha8 + 1.0 + + + color8 + "dark red" + + + label8 + + + + marker8 + -1 + + + style8 + 1 + + + width8 + 1 + + + alpha9 + 1.0 + + + color9 + "dark green" + + + label9 + + + + marker9 + -1 + + + style9 + 1 + + + width9 + 1 + + + name + "" + + + nconnections + 1 + + + size + 1024 + + + srate + samp_rate/sps/2 + + + stemplot + False + + + tr_chan + 0 + + + tr_delay + 0 + + + tr_level + 0.0 + + + tr_mode + qtgui.TRIG_MODE_AUTO + + + tr_slope + qtgui.TRIG_SLOPE_POS + + + tr_tag + "soft_dec" + + + type + msg_float + + + update_time + 0.10 + + + ylabel + soft_dec + + + yunit + "" + + + ymax + 7 + + + ymin + -7 + + qtgui_waterfall_sink_x @@ -1976,6 +2343,12 @@ 0 0 + + digitalhf_adaptive_dfe_0 + qtgui_time_sink_x_1 + soft_dec + in + preamble blocks_complex_to_mag_0 diff --git a/grc/digitalhf_adaptive_dfe.xml b/grc/digitalhf_adaptive_dfe.xml index cce5f29..1b3a9f3 100644 --- a/grc/digitalhf_adaptive_dfe.xml +++ b/grc/digitalhf_adaptive_dfe.xml @@ -73,4 +73,10 @@ complex + + + soft_dec + message + 1 + diff --git a/lib/adaptive_dfe_impl.cc b/lib/adaptive_dfe_impl.cc index 18390bc..65d58c8 100644 --- a/lib/adaptive_dfe_impl.cc +++ b/lib/adaptive_dfe_impl.cc @@ -28,7 +28,7 @@ #include "adaptive_dfe_impl.h" #define VOLK_SAFE_DELETE(x) \ - volk_free(x); \ + volk_free(x); \ x = nullptr namespace gr { @@ -108,12 +108,17 @@ adaptive_dfe_impl::adaptive_dfe_impl(int sps, // samples per symbol , _descrambled_symbols() , _symbol_counter(0) , _need_samples(false) + , _save_soft_decisions(false) + , _vec_soft_decisions() + , _msg_port_name(pmt::mp("soft_dec")) + , _msg_metadata(pmt::make_dict()) , _df(0) , _phase(0) , _b{0.338187046465954, -0.288839024460507} , _ud(0) , _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() { + _msg_port_name = pmt::PMT_NIL; + _msg_metadata = pmt::PMT_NIL; VOLK_SAFE_DELETE(_taps_samples); VOLK_SAFE_DELETE(_taps_symbols); VOLK_SAFE_DELETE(_hist_samples); @@ -246,6 +253,14 @@ adaptive_dfe_impl::general_work(int noutput_items, update_doppler_information(_physicalLayer.attr("get_doppler") (complex_vector_to_ndarray(_descrambled_symbols), 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(); update_frame_information(_physicalLayer.attr("get_frame")()); } catch (boost::python::error_already_set const&) { @@ -340,18 +355,19 @@ gr_complex adaptive_dfe_impl::filter() { gr_complex descrambled_symbol = 0; constell->map_to_points(jc, &descrambled_symbol); - // make soft decisions - float const err = std::abs(descrambled_filter_output - descrambled_symbol); - _npwr_counter[_constellation_index] += (_npwr_counter[_constellation_index] < _npwr_max_time_constant); - float const alpha = 1.0f/_npwr_counter[_constellation_index]; - _npwr[_constellation_index] = (1-alpha)*_npwr[_constellation_index] + alpha*err; - std::vector soft_dec = constell->calc_soft_dec(descrambled_filter_output, _npwr[_constellation_index]); - // std::cout << "soft_dec " << _npwr[_constellation_index] << " : "; - // for (int k=0; k const soft_dec = constell->calc_soft_dec(descrambled_filter_output, _npwr[_constellation_index]); + std::copy(soft_dec.begin(), soft_dec.end(), std::back_inserter >(_vec_soft_decisions)); + // std::cout << "soft_dec " << _npwr[_constellation_index] << " : "; + // for (int k=0; k(obj.attr("__len__")()); - assert(n==3); + assert(n==4); boost::python::numpy::ndarray array = boost::python::numpy::array(obj[0]); char const* data = array.get_data(); 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 (obj[1]); _need_samples = boost::python::extract(obj[2]); + _save_soft_decisions = boost::python::extract(obj[3]); return true; } bool adaptive_dfe_impl::update_doppler_information(boost::python::object obj) diff --git a/lib/adaptive_dfe_impl.h b/lib/adaptive_dfe_impl.h index 67f4e40..c877833 100644 --- a/lib/adaptive_dfe_impl.h +++ b/lib/adaptive_dfe_impl.h @@ -64,6 +64,10 @@ private: int _symbol_counter; bool _need_samples; + bool _save_soft_decisions; + std::vector _vec_soft_decisions; + pmt::pmt_t _msg_port_name; + pmt::pmt_t _msg_metadata; // PLL for doppler tracking float _df; // frequency offset in radians per sample diff --git a/python/physical_layer/STANAG_4285.py b/python/physical_layer/STANAG_4285.py index 7f4ff4d..0764ac2 100644 --- a/python/physical_layer/STANAG_4285.py +++ b/python/physical_layer/STANAG_4285.py @@ -34,9 +34,10 @@ class PhysicalLayer(object): """returns a tuple describing the frame: [0] ... known+unknown symbols and scrambling [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) - 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): """returns a tuple