diff --git a/examples/test_cc.grc b/examples/test_cc.grc index bc088ed..6741da8 100644 --- a/examples/test_cc.grc +++ b/examples/test_cc.grc @@ -34,7 +34,7 @@ _coordinate - (8, 8) + (10, 16) _rotation @@ -82,7 +82,7 @@ thread_safe_setters - + 1 title @@ -105,7 +105,7 @@ _coordinate - (266, 570) + (757, 16) _rotation @@ -132,15 +132,15 @@ _enabled - True + 0 _coordinate - (1130, 5) + (1120, 101) gui_hint - + (3,0,1,2) _rotation @@ -195,7 +195,7 @@ _coordinate - (320, 5) + (320, 16) _rotation @@ -222,7 +222,7 @@ _coordinate - (554, 5) + (533, 16) _rotation @@ -234,7 +234,7 @@ value - 10*sps + 12*sps @@ -249,7 +249,7 @@ _coordinate - (629, 5) + (608, 16) _rotation @@ -261,7 +261,7 @@ value - 10*sps + 9*sps @@ -276,7 +276,7 @@ _coordinate - (704, 5) + (682, 16) _rotation @@ -288,7 +288,7 @@ value - 4 + 5 @@ -303,7 +303,7 @@ _coordinate - (224, 5) + (224, 16) _rotation @@ -330,7 +330,7 @@ _coordinate - (480, 5) + (458, 16) _rotation @@ -365,7 +365,7 @@ _coordinate - (906, 421) + (906, 325) _rotation @@ -408,7 +408,7 @@ _coordinate - (234, 133) + (245, 165) _rotation @@ -455,7 +455,7 @@ _coordinate - (416, 154) + (416, 186) _rotation @@ -506,7 +506,7 @@ _coordinate - (1034, 282) + (949, 144) _rotation @@ -557,7 +557,7 @@ _coordinate - (576, 154) + (576, 186) _rotation @@ -612,11 +612,11 @@ file - /Users/chm/Downloads/sielsdr.ddns.net_2018-10-26T11_30_27Z_6768.50_iq.wav + /Users/chm/Software/signal-analysis/gnuradio/20181027T095433Z_6407800_SM2GCT_iq.wav _coordinate - (10, 133) + (10, 165) _rotation @@ -663,7 +663,7 @@ _coordinate - (85, 410) + (864, 453) _rotation @@ -718,7 +718,7 @@ _coordinate - (917, 10) + (1034, 21) _rotation @@ -749,7 +749,7 @@ _coordinate - (906, 64) + (960, 21) _rotation @@ -784,7 +784,7 @@ _coordinate - (746, 133) + (629, 282) _rotation @@ -820,7 +820,7 @@ threshold - 0.5 + 0.3 @@ -851,11 +851,11 @@ _coordinate - (469, 432) + (1088, 474) gui_hint - + (2,2,2,2) _rotation @@ -871,7 +871,7 @@ legend - True + False alpha1 @@ -883,7 +883,7 @@ label1 - + descrambled symbols marker1 @@ -1174,7 +1174,7 @@ qtgui_time_sink_x autoscale - True + False axislabels @@ -1206,11 +1206,11 @@ _coordinate - (1098, 410) + (1098, 314) gui_hint - + (2,0,1,2) _rotation @@ -1226,7 +1226,7 @@ legend - True + False alpha1 @@ -1238,7 +1238,7 @@ label1 - err + preamble cross-correlation marker1 @@ -1530,380 +1530,13 @@ ymax - 800 + 300 ymin 0 - - qtgui_time_sink_x - - autoscale - True - - - axislabels - True - - - alias - - - - comment - - - - ctrlpanel - False - - - affinity - - - - entags - True - - - _enabled - True - - - _coordinate - (1077, 197) - - - gui_hint - - - - _rotation - 0 - - - grid - False - - - id - qtgui_time_sink_x_0_0 - - - legend - True - - - alpha1 - 1.0 - - - color1 - "blue" - - - label1 - I - - - marker1 - -1 - - - style1 - 1 - - - width1 - 1 - - - alpha10 - 1.0 - - - color10 - "blue" - - - label10 - - - - marker10 - -1 - - - style10 - 1 - - - width10 - 1 - - - alpha2 - 1.0 - - - color2 - "red" - - - label2 - Q - - - marker2 - -1 - - - style2 - 1 - - - width2 - 1 - - - alpha3 - 1.0 - - - color3 - "green" - - - label3 - phase - - - 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 - - - stemplot - False - - - tr_chan - 0 - - - tr_delay - 0.02 - - - tr_level - 0.0 - - - tr_mode - qtgui.TRIG_MODE_TAG - - - tr_slope - qtgui.TRIG_SLOPE_POS - - - tr_tag - "time_est" - - - type - complex - - - update_time - .1 - - - ylabel - preamble correlation - - - yunit - "" - - - ymax - 2 - - - ymin - -2 - - qtgui_waterfall_sink_x @@ -1936,15 +1569,15 @@ fftsize - 128 + 1024*4 _coordinate - (1077, 112) + (1098, 229) gui_hint - + (0,0,2,4) _rotation @@ -1964,7 +1597,7 @@ int_min - -140 + -80 legend @@ -2187,12 +1820,6 @@ 0 0 - - preamble - qtgui_time_sink_x_0_0 - 0 - 0 - preamble qtgui_waterfall_sink_x_0 diff --git a/lib/adaptive_dfe_impl.cc b/lib/adaptive_dfe_impl.cc index 3892efc..9024d98 100644 --- a/lib/adaptive_dfe_impl.cc +++ b/lib/adaptive_dfe_impl.cc @@ -73,7 +73,7 @@ adaptive_dfe_impl::adaptive_dfe_impl(int sps, // samples per symbol , _nF(nF) , _nW(nW) , _mu(0.01) - , _alpha(0.0005) + , _alpha(0.001) , _py_module_name(python_module_name) , _physicalLayer() , _taps_samples(nullptr) @@ -212,25 +212,23 @@ adaptive_dfe_impl::general_work(int noutput_items, known_symbol = _scramble[_symbol_counter] * descrambled_filter_output; } gr_complex err = filter_output - known_symbol; - if (_symbol_counter >= 0) { - for (int j=0; j<_nB+_nF+1; ++j) { - _taps_samples[j] -= _mu*err*std::conj(_hist_samples[_hist_sample_index+j]); - } - for (int j=0; j<_nW; ++j) { - assert(_hist_symbol_index+j < 2*_nW); - _taps_symbols[j] -= _mu*err*std::conj(_hist_symbols[_hist_symbol_index+j]) + _alpha*_taps_symbols[j]; - } + for (int j=0; j<_nB+_nF+1; ++j) { + _taps_samples[j] -= _mu*err*std::conj(_hist_samples[_hist_sample_index+j]); + } + for (int j=0; j<_nW; ++j) { + assert(_hist_symbol_index+j < 2*_nW); + _taps_symbols[j] -= _mu*err*std::conj(_hist_symbols[_hist_symbol_index+j]) + _alpha*_taps_symbols[j]; } // if (_sample_counter < 80*5) // std::cout << "filter: " << _symbol_counter << " " << _sample_counter << " " << filter_output << " " << known_symbol << " " << std::abs(err) << std::endl; } - if (is_known) { + if (is_known || true) { _taps_symbols[_hist_symbol_index] = _taps_symbols[_hist_symbol_index + _nW] = known_symbol; if (++_hist_symbol_index == _nW) _hist_symbol_index = 0; } _descrambled_symbols[_symbol_counter] = filter_output*std::conj(_scramble[_symbol_counter]); - out[nout++] = filter_output; + out[nout++] = filter_output*std::conj(_scramble[_symbol_counter]); ++_symbol_counter; } _sample_counter += 1; @@ -330,8 +328,16 @@ void adaptive_dfe_impl::update_doppler_information(boost::python::object obj) int const n = boost::python::extract(obj.attr("__len__")()); assert(n==2); bool const do_continue = boost::python::extract(obj[0]); + if (!do_continue) { + _state = WAIT_FOR_PREAMBLE; + _phase = 0; + _df = 0; + std::fill_n(_hist_samples, 2*(_nB+_nF+1), gr_complex(0)); + _hist_sample_index = 0; + _sample_counter = 0; + return; + } float const doppler = boost::python::extract(obj[1]); - update_pll(doppler); } @@ -373,7 +379,7 @@ bool adaptive_dfe_impl::get_correlation_tag(uint64_t i, uint64_t& offset, float& } if (v[j].key == pmt::mp("corr_est")) { double const corr_est = pmt::to_double(v[j].value); - if (v[j].offset - nitems_read(0) == offset)// && corr_est > 18e3) + if (v[j].offset - nitems_read(0) == offset)// && corr_est > 10e3) return true; } } diff --git a/python/physical_layer/STANAG_4285.py b/python/physical_layer/STANAG_4285.py index 3c6646b..e68a12e 100644 --- a/python/physical_layer/STANAG_4285.py +++ b/python/physical_layer/STANAG_4285.py @@ -6,7 +6,7 @@ from gnuradio import digital class PhysicalLayer(object): """Physical layer description for STANAG 4285""" - def __init__(self, mode=0): + def __init__(self, mode=1): """For STANAG 4258 the mode has to be set manually: mode=0 -> BPSK, mode=1 -> QPSK, mode=2 -> 8PSK""" self._constellations = [PhysicalLayer.make_psk(2, [0,1]), PhysicalLayer.make_psk(4, [0,1,3,2]), @@ -14,7 +14,7 @@ class PhysicalLayer(object): self._preamble = [PhysicalLayer.get_preamble(), 0] ## BPSK self._data = [PhysicalLayer.get_data(), mode] ## according to the mode self._counter = 0 - self._preamble_phases = [] + self._is_first_frame = True def set_mode(self, mode): """For STANAG 4258 the mode has to be set manually: mode=0 -> BPSK, mode=1 -> QPSK, mode=2 -> 8PSK""" @@ -26,22 +26,30 @@ class PhysicalLayer(object): def get_frame(self): """returns the known+unknown symbols and scrambling""" print('-------------------- get_frame --------------------',self._counter) - if self._counter == 0: - x= self._preamble - else: - x=self._data - print('get_frame end\n') - return x; + return self._preamble if self._counter == 0 else self._data def get_doppler(self, s): """used for doppler shift update, for determining which frame to provide next, and for stopping at end of data/when the signal quality is too low""" print('-------------------- get_doppler --------------------',self._counter) - doppler = 0 - if self._counter == 0: ## preamble - doppler = PhysicalLayer.data_aided_frequency_estimation(s, self._preamble[0]['symb']) - self._counter = (self._counter+1)&1 - return [True, doppler] + success,doppler = self.quality_preamble(s) if self._counter == 0 else self.quality_data(s) + self._counter = (self._counter+1)&1 if success else 0 + self._is_first_frame = not success + return success,doppler + + def quality_preamble(self, s): + idx = range(80) + if self._is_first_frame: + idx = range(30,80) + z = s[idx]*np.conj(self._preamble[0]['symb'][idx]) + success = np.sum(np.real(z)<0) < 30 + doppler = PhysicalLayer.data_aided_frequency_estimation(s[idx], self._preamble[0]['symb'][idx]) + return success,doppler + + def quality_data(self, s): + known_symbols = np.mod(range(176),48)>=32 + success = np.sum(np.real(s[known_symbols])<0) < 20 + return success,0 ## no doppler estimate for data frames @staticmethod def get_preamble(): @@ -73,9 +81,8 @@ class PhysicalLayer(object): ## PSK-8 modulation constellation = PhysicalLayer.make_psk(8,range(8))['points'] a['scramble'] = constellation[p,] - a['symb'][ 32: 48] = a['scramble'][ 32: 48] ## mini-probe 1 - a['symb'][ 80: 96] = a['scramble'][ 80: 96] ## mini-probe 2 - a['symb'][128:144] = a['scramble'][128:144] ## mini-probe 3 + known_symbols = np.mod(range(176),48)>=32 + a['symb'][known_symbols] = a['scramble'][known_symbols] return a @staticmethod