From 1cc5e64256fd61eb186c392101da464815ee4d85 Mon Sep 17 00:00:00 2001 From: cmayer Date: Sat, 3 Nov 2018 21:21:05 +0100 Subject: [PATCH] bug fixed * the big switch statement in lib/adaptive_dfe_impl.cc needs to be improved --- examples/.gitignore | 2 + examples/test_188-110A.grc | 2385 +++++++++++++++++++++ examples/test_188-110C.grc | 2385 +++++++++++++++++++++ lib/adaptive_dfe_impl.cc | 256 +-- python/physical_layer/MIL_STD_188_110C.py | 232 ++ 5 files changed, 5137 insertions(+), 123 deletions(-) create mode 100644 examples/.gitignore create mode 100644 examples/test_188-110A.grc create mode 100644 examples/test_188-110C.grc create mode 100644 python/physical_layer/MIL_STD_188_110C.py diff --git a/examples/.gitignore b/examples/.gitignore new file mode 100644 index 0000000..fb0c288 --- /dev/null +++ b/examples/.gitignore @@ -0,0 +1,2 @@ +top_block.py +*.wav \ No newline at end of file diff --git a/examples/test_188-110A.grc b/examples/test_188-110A.grc new file mode 100644 index 0000000..876d805 --- /dev/null +++ b/examples/test_188-110A.grc @@ -0,0 +1,2385 @@ + + + + Fri Oct 19 14:08:05 2018 + + options + + author + + + + window_size + + + + category + [GRC Hier Blocks] + + + comment + + + + copyright + + + + description + + + + _enabled + True + + + _coordinate + (10, 16) + + + _rotation + 0 + + + generate_options + qt_gui + + + hier_block_src_path + .: + + + id + top_block + + + max_nouts + 0 + + + qt_qss_theme + + + + realtime_scheduling + + + + run_command + {python} -u {filename} + + + run_options + prompt + + + run + True + + + sizing_mode + fixed + + + thread_safe_setters + 1 + + + title + + + + placement + (0,0) + + + + variable_qtgui_range + + comment + + + + value + 4932 + + + _enabled + 0 + + + _coordinate + (1141, 80) + + + gui_hint + (3,0,1,2) + + + _rotation + 0 + + + id + freq + + + label + frequency + + + min_len + 200 + + + orient + Qt.Horizontal + + + start + 0 + + + step + 0.0001 + + + stop + 30e3 + + + rangeType + float + + + widget + counter_slider + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (320, 16) + + + _rotation + 0 + + + id + lpz + + + value + MIL_STD_188_110A.PhysicalLayer.get_preamble_z(sps).tolist() + + + + variable_qtgui_range + + comment + + + + value + 0.001 + + + _enabled + True + + + _coordinate + (1024, 80) + + + gui_hint + (3,0,1,2) + + + _rotation + 0 + + + id + mu + + + label + mu + + + min_len + 200 + + + orient + Qt.Horizontal + + + start + 0.0001 + + + step + 0.0001 + + + stop + 0.01 + + + rangeType + float + + + widget + counter_slider + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (533, 16) + + + _rotation + 0 + + + id + nB + + + value + 9 + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (608, 16) + + + _rotation + 0 + + + id + nF + + + value + 9 + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (682, 16) + + + _rotation + 0 + + + id + nW + + + value + 4 + + + + variable_rrc_filter_taps + + comment + + + + _enabled + 1 + + + alpha + 0.35 + + + _coordinate + (469, 352) + + + _rotation + 0 + + + gain + 1.0 + + + id + rrc_taps + + + ntaps + 11*sps + + + samp_rate + samp_rate + + + sym_rate + samp_rate/sps + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (224, 16) + + + _rotation + 0 + + + id + samp_rate + + + value + 12001 + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (458, 16) + + + _rotation + 0 + + + id + sps + + + value + 5 + + + + blocks_complex_to_mag + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (928, 314) + + + _rotation + 0 + + + id + blocks_complex_to_mag_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + vlen + 1 + + + + blocks_float_to_complex + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (256, 154) + + + _rotation + 0 + + + id + blocks_float_to_complex_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + vlen + 1 + + + + blocks_multiply_const_vxx + + alias + + + + comment + + + + const + 5 + + + affinity + + + + _enabled + True + + + _coordinate + (426, 176) + + + _rotation + 0 + + + id + blocks_multiply_const_vxx_0 + + + type + complex + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + vlen + 1 + + + + blocks_tag_debug + + alias + + + + comment + + + + affinity + + + + display + True + + + _enabled + 0 + + + _coordinate + (917, 133) + + + _rotation + 0 + + + id + blocks_tag_debug_0 + + + type + complex + + + filter + "" + + + name + + + + num_inputs + 1 + + + vlen + 1 + + + + blocks_throttle + + alias + + + + comment + + + + affinity + + + + _enabled + 1 + + + _coordinate + (586, 176) + + + _rotation + 0 + + + id + blocks_throttle_0 + + + ignoretag + True + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samples_per_second + samp_rate + + + type + complex + + + vlen + 1 + + + + blocks_wavfile_source + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + file + /Users/chm/Software/signal-analysis/20181104T143753Z_5680800_SM2KOT_iq.wav + + + _coordinate + (10, 154) + + + _rotation + 0 + + + id + blocks_wavfile_source_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + nchan + 2 + + + repeat + False + + + + digitalhf_adaptive_dfe + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (874, 389) + + + _rotation + 0 + + + id + digitalhf_adaptive_dfe_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + sps + sps + + + alpha + 0.0005 + + + mode + '' + + + mu + mu + + + nB + nB + + + nF + nF + + + nW + nW + + + py_obj_name + MIL_STD_188_110A + + + + fir_filter_xxx + + alias + + + + comment + + + + affinity + + + + decim + 1 + + + _enabled + 1 + + + _coordinate + (330, 293) + + + _rotation + 0 + + + id + fir_filter_xxx_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samp_delay + 0 + + + taps + rrc_taps + + + type + ccc + + + + import + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (1034, 21) + + + _rotation + 0 + + + id + import_0 + + + import + import digitalhf.physical_layer.MIL_STD_188_110A as MIL_STD_188_110A + + + + import + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (960, 21) + + + _rotation + 0 + + + id + import_0_0 + + + import + from gnuradio import gr + + + + import + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (810, 32) + + + _rotation + 0 + + + id + import_1 + + + import + import numpy as np + + + + digital_corr_est_cc + + alias + + + + comment + + + + affinity + + + + _enabled + 1 + + + _coordinate + (640, 272) + + + _rotation + 0 + + + id + preamble + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + sps + sps + + + symbols + lpz + + + mark_delay + nF*sps-2 + + + threshold_method + digital.corr_est_cc.THRESHOLD_DYNAMIC + + + threshold + 0.35 + + + + qtgui_const_sink_x + + autoscale + False + + + axislabels + True + + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (1109, 410) + + + gui_hint + (2,2,3,2) + + + _rotation + 0 + + + grid + True + + + id + qtgui_const_sink_x_0 + + + legend + False + + + alpha1 + 1 + + + color1 + "blue" + + + label1 + descrambled symbols + + + marker1 + 0 + + + style1 + 0 + + + width1 + 1 + + + alpha10 + 1.0 + + + color10 + "red" + + + label10 + + + + marker10 + 0 + + + style10 + 0 + + + width10 + 1 + + + alpha2 + 1.0 + + + color2 + "red" + + + label2 + + + + marker2 + 0 + + + style2 + 0 + + + width2 + 1 + + + alpha3 + 1.0 + + + color3 + "red" + + + label3 + + + + marker3 + 0 + + + style3 + 0 + + + width3 + 1 + + + alpha4 + 1.0 + + + color4 + "red" + + + label4 + + + + marker4 + 0 + + + style4 + 0 + + + width4 + 1 + + + alpha5 + 1.0 + + + color5 + "red" + + + label5 + + + + marker5 + 0 + + + style5 + 0 + + + width5 + 1 + + + alpha6 + 1.0 + + + color6 + "red" + + + label6 + + + + marker6 + 0 + + + style6 + 0 + + + width6 + 1 + + + alpha7 + 1.0 + + + color7 + "red" + + + label7 + + + + marker7 + 0 + + + style7 + 0 + + + width7 + 1 + + + alpha8 + 1.0 + + + color8 + "red" + + + label8 + + + + marker8 + 0 + + + style8 + 0 + + + width8 + 1 + + + alpha9 + 1.0 + + + color9 + "red" + + + label9 + + + + marker9 + 0 + + + style9 + 0 + + + width9 + 1 + + + name + "" + + + nconnections + 1 + + + size + 1024 + + + tr_chan + 0 + + + tr_level + 0.0 + + + tr_mode + qtgui.TRIG_MODE_FREE + + + tr_slope + qtgui.TRIG_SLOPE_POS + + + tr_tag + "" + + + type + complex + + + update_time + 0.1 + + + xmax + 2 + + + xmin + -2 + + + ymax + 2 + + + ymin + -2 + + + + qtgui_time_sink_x + + autoscale + False + + + axislabels + True + + + alias + + + + comment + + + + ctrlpanel + False + + + affinity + + + + entags + True + + + _enabled + True + + + _coordinate + (1120, 304) + + + gui_hint + (2,0,1,2) + + + _rotation + 0 + + + grid + False + + + id + qtgui_time_sink_x_0 + + + legend + False + + + alpha1 + 1.0 + + + color1 + "blue" + + + label1 + preamble cross-correlation + + + marker1 + -1 + + + style1 + 1 + + + width1 + 1 + + + alpha10 + 1.0 + + + color10 + "blue" + + + label10 + + + + marker10 + -1 + + + style10 + 1 + + + width10 + 1 + + + alpha2 + 1.0 + + + color2 + "red" + + + label2 + rate + + + 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.01 + + + tr_level + 0.0 + + + tr_mode + qtgui.TRIG_MODE_TAG + + + tr_slope + qtgui.TRIG_SLOPE_POS + + + tr_tag + "time_est" + + + type + float + + + update_time + .1 + + + ylabel + preamble correlation + + + yunit + "" + + + ymax + 1000 + + + ymin + 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 + + axislabels + True + + + bw + samp_rate + + + alias + + + + fc + 0 + + + comment + + + + affinity + + + + _enabled + True + + + fftsize + 1024*4 + + + _coordinate + (1120, 218) + + + gui_hint + (0,0,2,4) + + + _rotation + 0 + + + grid + False + + + id + qtgui_waterfall_sink_x_0 + + + int_max + 10 + + + int_min + -80 + + + legend + True + + + alpha1 + 1.0 + + + color1 + 0 + + + label1 + + + + alpha10 + 1.0 + + + color10 + 0 + + + label10 + + + + alpha2 + 1.0 + + + color2 + 0 + + + label2 + + + + alpha3 + 1.0 + + + color3 + 0 + + + label3 + + + + alpha4 + 1.0 + + + color4 + 0 + + + label4 + + + + alpha5 + 1.0 + + + color5 + 0 + + + label5 + + + + alpha6 + 1.0 + + + color6 + 0 + + + label6 + + + + alpha7 + 1.0 + + + color7 + 0 + + + label7 + + + + alpha8 + 1.0 + + + color8 + 0 + + + label8 + + + + alpha9 + 1.0 + + + color9 + 0 + + + label9 + + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + name + "" + + + nconnections + 1 + + + showports + True + + + freqhalf + True + + + type + complex + + + update_time + 0.10 + + + wintype + firdes.WIN_BLACKMAN_hARRIS + + + + blocks_complex_to_mag_0 + qtgui_time_sink_x_0 + 0 + 0 + + + blocks_float_to_complex_0 + blocks_multiply_const_vxx_0 + 0 + 0 + + + blocks_multiply_const_vxx_0 + blocks_throttle_0 + 0 + 0 + + + blocks_throttle_0 + fir_filter_xxx_0 + 0 + 0 + + + blocks_wavfile_source_0 + blocks_float_to_complex_0 + 0 + 0 + + + blocks_wavfile_source_0 + blocks_float_to_complex_0 + 1 + 1 + + + digitalhf_adaptive_dfe_0 + qtgui_const_sink_x_0 + 0 + 0 + + + digitalhf_adaptive_dfe_0 + qtgui_time_sink_x_1 + soft_dec + in + + + fir_filter_xxx_0 + preamble + 0 + 0 + + + preamble + blocks_complex_to_mag_0 + 1 + 0 + + + preamble + blocks_tag_debug_0 + 0 + 0 + + + preamble + digitalhf_adaptive_dfe_0 + 0 + 0 + + + preamble + qtgui_waterfall_sink_x_0 + 0 + 0 + + diff --git a/examples/test_188-110C.grc b/examples/test_188-110C.grc new file mode 100644 index 0000000..e6ac025 --- /dev/null +++ b/examples/test_188-110C.grc @@ -0,0 +1,2385 @@ + + + + Fri Oct 19 14:08:05 2018 + + options + + author + + + + window_size + + + + category + [GRC Hier Blocks] + + + comment + + + + copyright + + + + description + + + + _enabled + True + + + _coordinate + (10, 16) + + + _rotation + 0 + + + generate_options + qt_gui + + + hier_block_src_path + .: + + + id + top_block + + + max_nouts + 0 + + + qt_qss_theme + + + + realtime_scheduling + + + + run_command + {python} -u {filename} + + + run_options + prompt + + + run + True + + + sizing_mode + fixed + + + thread_safe_setters + 1 + + + title + + + + placement + (0,0) + + + + variable_qtgui_range + + comment + + + + value + 4932 + + + _enabled + 0 + + + _coordinate + (1141, 80) + + + gui_hint + (3,0,1,2) + + + _rotation + 0 + + + id + freq + + + label + frequency + + + min_len + 200 + + + orient + Qt.Horizontal + + + start + 0 + + + step + 0.0001 + + + stop + 30e3 + + + rangeType + float + + + widget + counter_slider + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (320, 16) + + + _rotation + 0 + + + id + lpz + + + value + MIL_STD_188_110C.PhysicalLayer.get_preamble_z(sps).tolist() + + + + variable_qtgui_range + + comment + + + + value + 0.005 + + + _enabled + True + + + _coordinate + (1024, 80) + + + gui_hint + (3,0,1,2) + + + _rotation + 0 + + + id + mu + + + label + mu + + + min_len + 200 + + + orient + Qt.Horizontal + + + start + 0.0001 + + + step + 0.0001 + + + stop + 0.01 + + + rangeType + float + + + widget + counter_slider + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (533, 16) + + + _rotation + 0 + + + id + nB + + + value + 9 + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (608, 16) + + + _rotation + 0 + + + id + nF + + + value + 9 + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (682, 16) + + + _rotation + 0 + + + id + nW + + + value + 4 + + + + variable_rrc_filter_taps + + comment + + + + _enabled + 1 + + + alpha + 0.35 + + + _coordinate + (469, 352) + + + _rotation + 0 + + + gain + 1.0 + + + id + rrc_taps + + + ntaps + 11*sps + + + samp_rate + samp_rate + + + sym_rate + samp_rate/sps + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (224, 16) + + + _rotation + 0 + + + id + samp_rate + + + value + 12001 + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (458, 16) + + + _rotation + 0 + + + id + sps + + + value + 5 + + + + blocks_complex_to_mag + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (928, 314) + + + _rotation + 0 + + + id + blocks_complex_to_mag_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + vlen + 1 + + + + blocks_float_to_complex + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (256, 154) + + + _rotation + 0 + + + id + blocks_float_to_complex_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + vlen + 1 + + + + blocks_multiply_const_vxx + + alias + + + + comment + + + + const + 5 + + + affinity + + + + _enabled + True + + + _coordinate + (426, 176) + + + _rotation + 0 + + + id + blocks_multiply_const_vxx_0 + + + type + complex + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + vlen + 1 + + + + blocks_tag_debug + + alias + + + + comment + + + + affinity + + + + display + True + + + _enabled + 0 + + + _coordinate + (917, 133) + + + _rotation + 0 + + + id + blocks_tag_debug_0 + + + type + complex + + + filter + "" + + + name + + + + num_inputs + 1 + + + vlen + 1 + + + + blocks_throttle + + alias + + + + comment + + + + affinity + + + + _enabled + 1 + + + _coordinate + (586, 176) + + + _rotation + 0 + + + id + blocks_throttle_0 + + + ignoretag + True + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samples_per_second + samp_rate + + + type + complex + + + vlen + 1 + + + + blocks_wavfile_source + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + file + /Users/chm/Software/signal-analysis/gnuradio/20181026T063629Z_7815000_SM2GCT_iq.wav + + + _coordinate + (10, 154) + + + _rotation + 0 + + + id + blocks_wavfile_source_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + nchan + 2 + + + repeat + True + + + + digitalhf_adaptive_dfe + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (874, 389) + + + _rotation + 0 + + + id + digitalhf_adaptive_dfe_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + sps + sps + + + alpha + 0.0005 + + + mode + '' + + + mu + mu + + + nB + nB + + + nF + nF + + + nW + nW + + + py_obj_name + MIL_STD_188_110C + + + + fir_filter_xxx + + alias + + + + comment + + + + affinity + + + + decim + 1 + + + _enabled + 1 + + + _coordinate + (330, 293) + + + _rotation + 0 + + + id + fir_filter_xxx_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samp_delay + 0 + + + taps + rrc_taps + + + type + ccc + + + + import + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (1034, 21) + + + _rotation + 0 + + + id + import_0 + + + import + import digitalhf.physical_layer.MIL_STD_188_110C as MIL_STD_188_110C + + + + import + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (960, 21) + + + _rotation + 0 + + + id + import_0_0 + + + import + from gnuradio import gr + + + + import + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (810, 32) + + + _rotation + 0 + + + id + import_1 + + + import + import numpy as np + + + + digital_corr_est_cc + + alias + + + + comment + + + + affinity + + + + _enabled + 1 + + + _coordinate + (640, 272) + + + _rotation + 0 + + + id + preamble + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + sps + sps + + + symbols + lpz + + + mark_delay + nF*sps-2 + + + threshold_method + digital.corr_est_cc.THRESHOLD_DYNAMIC + + + threshold + 0.5 + + + + qtgui_const_sink_x + + autoscale + False + + + axislabels + True + + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (1109, 410) + + + gui_hint + (2,2,3,2) + + + _rotation + 0 + + + grid + True + + + id + qtgui_const_sink_x_0 + + + legend + False + + + alpha1 + 1 + + + color1 + "blue" + + + label1 + descrambled symbols + + + marker1 + 0 + + + style1 + 0 + + + width1 + 1 + + + alpha10 + 1.0 + + + color10 + "red" + + + label10 + + + + marker10 + 0 + + + style10 + 0 + + + width10 + 1 + + + alpha2 + 1.0 + + + color2 + "red" + + + label2 + + + + marker2 + 0 + + + style2 + 0 + + + width2 + 1 + + + alpha3 + 1.0 + + + color3 + "red" + + + label3 + + + + marker3 + 0 + + + style3 + 0 + + + width3 + 1 + + + alpha4 + 1.0 + + + color4 + "red" + + + label4 + + + + marker4 + 0 + + + style4 + 0 + + + width4 + 1 + + + alpha5 + 1.0 + + + color5 + "red" + + + label5 + + + + marker5 + 0 + + + style5 + 0 + + + width5 + 1 + + + alpha6 + 1.0 + + + color6 + "red" + + + label6 + + + + marker6 + 0 + + + style6 + 0 + + + width6 + 1 + + + alpha7 + 1.0 + + + color7 + "red" + + + label7 + + + + marker7 + 0 + + + style7 + 0 + + + width7 + 1 + + + alpha8 + 1.0 + + + color8 + "red" + + + label8 + + + + marker8 + 0 + + + style8 + 0 + + + width8 + 1 + + + alpha9 + 1.0 + + + color9 + "red" + + + label9 + + + + marker9 + 0 + + + style9 + 0 + + + width9 + 1 + + + name + "" + + + nconnections + 1 + + + size + 512 + + + tr_chan + 0 + + + tr_level + 0.0 + + + tr_mode + qtgui.TRIG_MODE_FREE + + + tr_slope + qtgui.TRIG_SLOPE_POS + + + tr_tag + "" + + + type + complex + + + update_time + 0.1 + + + xmax + 2 + + + xmin + -2 + + + ymax + 2 + + + ymin + -2 + + + + qtgui_time_sink_x + + autoscale + False + + + axislabels + True + + + alias + + + + comment + + + + ctrlpanel + False + + + affinity + + + + entags + True + + + _enabled + True + + + _coordinate + (1120, 304) + + + gui_hint + (2,0,1,2) + + + _rotation + 0 + + + grid + False + + + id + qtgui_time_sink_x_0 + + + legend + False + + + alpha1 + 1.0 + + + color1 + "blue" + + + label1 + preamble cross-correlation + + + marker1 + -1 + + + style1 + 1 + + + width1 + 1 + + + alpha10 + 1.0 + + + color10 + "blue" + + + label10 + + + + marker10 + -1 + + + style10 + 1 + + + width10 + 1 + + + alpha2 + 1.0 + + + color2 + "red" + + + label2 + rate + + + 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.01 + + + tr_level + 0.0 + + + tr_mode + qtgui.TRIG_MODE_TAG + + + tr_slope + qtgui.TRIG_SLOPE_POS + + + tr_tag + "time_est" + + + type + float + + + update_time + .1 + + + ylabel + preamble correlation + + + yunit + "" + + + ymax + 1000 + + + ymin + 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 + + axislabels + True + + + bw + samp_rate + + + alias + + + + fc + 0 + + + comment + + + + affinity + + + + _enabled + True + + + fftsize + 1024*4 + + + _coordinate + (1120, 218) + + + gui_hint + (0,0,2,4) + + + _rotation + 0 + + + grid + False + + + id + qtgui_waterfall_sink_x_0 + + + int_max + 10 + + + int_min + -80 + + + legend + True + + + alpha1 + 1.0 + + + color1 + 0 + + + label1 + + + + alpha10 + 1.0 + + + color10 + 0 + + + label10 + + + + alpha2 + 1.0 + + + color2 + 0 + + + label2 + + + + alpha3 + 1.0 + + + color3 + 0 + + + label3 + + + + alpha4 + 1.0 + + + color4 + 0 + + + label4 + + + + alpha5 + 1.0 + + + color5 + 0 + + + label5 + + + + alpha6 + 1.0 + + + color6 + 0 + + + label6 + + + + alpha7 + 1.0 + + + color7 + 0 + + + label7 + + + + alpha8 + 1.0 + + + color8 + 0 + + + label8 + + + + alpha9 + 1.0 + + + color9 + 0 + + + label9 + + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + name + "" + + + nconnections + 1 + + + showports + True + + + freqhalf + True + + + type + complex + + + update_time + 0.10 + + + wintype + firdes.WIN_BLACKMAN_hARRIS + + + + blocks_complex_to_mag_0 + qtgui_time_sink_x_0 + 0 + 0 + + + blocks_float_to_complex_0 + blocks_multiply_const_vxx_0 + 0 + 0 + + + blocks_multiply_const_vxx_0 + blocks_throttle_0 + 0 + 0 + + + blocks_throttle_0 + fir_filter_xxx_0 + 0 + 0 + + + blocks_wavfile_source_0 + blocks_float_to_complex_0 + 0 + 0 + + + blocks_wavfile_source_0 + blocks_float_to_complex_0 + 1 + 1 + + + digitalhf_adaptive_dfe_0 + qtgui_const_sink_x_0 + 0 + 0 + + + digitalhf_adaptive_dfe_0 + qtgui_time_sink_x_1 + soft_dec + in + + + fir_filter_xxx_0 + preamble + 0 + 0 + + + preamble + blocks_complex_to_mag_0 + 1 + 0 + + + preamble + blocks_tag_debug_0 + 0 + 0 + + + preamble + digitalhf_adaptive_dfe_0 + 0 + 0 + + + preamble + qtgui_waterfall_sink_x_0 + 0 + 0 + + diff --git a/lib/adaptive_dfe_impl.cc b/lib/adaptive_dfe_impl.cc index 8b56319..4673800 100644 --- a/lib/adaptive_dfe_impl.cc +++ b/lib/adaptive_dfe_impl.cc @@ -159,68 +159,93 @@ adaptive_dfe_impl::general_work(int noutput_items, gr_complex const* in = (gr_complex const *)input_items[0]; gr_complex *out = (gr_complex *)output_items[0]; - int nout = 0; - int i = 0; + int nout = 0; // counter for produced output items + int i = 0; // counter for consumed input items for (; i const empty_vec; - // initial doppler estimate - if (!update_doppler_information(_physicalLayer.attr("get_doppler") - (complex_vector_to_ndarray(empty_vec), - complex_vector_to_ndarray(_samples)))) { - _state = WAIT_FOR_PREAMBLE; - continue; + switch (_state) { + case WAIT_FOR_PREAMBLE: { + insert_sample(in[i++]); + uint64_t offset = 0; + float phase_est = 0; + if (get_correlation_tag(i, offset, phase_est)) { + GR_LOG_DEBUG(d_logger, "next state > INITIAL_DOPPLER_ESTIMATE"); + _state = INITIAL_DOPPLER_ESTIMATE; + _sample_counter = 0; + _symbol_counter = 0; + // _symbols.clear(); + // _scramble.clear(); + _descrambled_symbols.clear(); + // _hist_sample_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(_taps_samples, _nB+_nF+1, gr_complex(0)); + std::fill_n(_taps_symbols, _nW, gr_complex(0)); + _samples.clear(); + _phase = -phase_est; + _taps_samples[_nB+1] = 0.01; + _taps_symbols[0] = 1; + GILLock gil_lock; + try { + update_frame_information(_physicalLayer.attr("get_frame")()); + } catch (boost::python::error_already_set const&) { + PyErr_Print(); } - } catch (boost::python::error_already_set const&) { - PyErr_Print(); } - // (1) correct all samples in the circular buffer with the inital doppler estimate - for (int j=_nB+1; j<_nB+_nF+1; ++j) { - assert(_hist_sample_index+j < 2*(_nB+_nF+1)); - _hist_samples[_hist_sample_index+j] *= gr_expj(-_phase); - update_local_oscillator(); + break; + } // WAIT_FOR_PREAMBLE + + case INITIAL_DOPPLER_ESTIMATE: { + _samples.push_back(in[i++]); + // buffer samples and replay them later once the initial doppler estimate is there + if (_samples.size() == _sps * _symbols.size()) { + GILLock gil_lock; + try { + std::vector const empty_vec; + // initial doppler estimate + if (!update_doppler_information(_physicalLayer.attr("get_doppler") + (complex_vector_to_ndarray(empty_vec), + complex_vector_to_ndarray(_samples)))) { + GR_LOG_DEBUG(d_logger, "next state > WAIT_FOR_PREAMBLE"); + _state = WAIT_FOR_PREAMBLE; + break; + } + } catch (boost::python::error_already_set const&) { + PyErr_Print(); + } + // (1) correct all samples in the circular buffer with the inital doppler estimate + for (int j=_nB+1; j<_nB+_nF+1; ++j) { + assert(_hist_sample_index+j < 2*(_nB+_nF+1)); + _hist_samples[_hist_sample_index+j] *= gr_expj(-_phase); + update_local_oscillator(); + } + // (2) insert all buffered samples and run the adaptive filter for them + // instead of pop_front() we first reverse _samples and then insert back() + pop_back() + // O(N) instead of O(N^2) + std::reverse(_samples.begin(), _samples.end()); + while (!_samples.empty() && nout < noutput_items) { + insert_sample(_samples.back()); + _sample_counter += 1; + _samples.pop_back(); + if ((_sample_counter%_sps) == 0) + out[nout++] = filter(); + } + if (_samples.empty()) { + GR_LOG_DEBUG(d_logger,"next state > DO_FILTER"); + _state = DO_FILTER; + break; + } else { + GR_LOG_DEBUG(d_logger, "next state > INITIAL_DOPPLER_ESTIMATE_CONTINUE"); + _state = INITIAL_DOPPLER_ESTIMATE_CONTINUE; + break; + } } - // (2) insert all buffered samples and run the adaptive filter for them - // instead of pop_front() we first reverse _samples and then insert back() + pop_back() - // O(N) instead of O(N^2) - std::reverse(_samples.begin(), _samples.end()); + } // INITIAL_DOPPLER_ESTIMATE_CONTINUE + + case INITIAL_DOPPLER_ESTIMATE_CONTINUE: { + GR_LOG_DEBUG(d_logger, "INITIAL_DOPPLER_ESTIMATE_CONTINUE"); while (!_samples.empty() && nout < noutput_items) { insert_sample(_samples.back()); _sample_counter += 1; @@ -229,79 +254,65 @@ adaptive_dfe_impl::general_work(int noutput_items, out[nout++] = filter(); } if (_samples.empty()) { + GR_LOG_DEBUG(d_logger, "next state > DO_FILTER"); _state = DO_FILTER; } else { + GR_LOG_DEBUG(d_logger, "next state > INITIAL_DOPPLER_ESTIMATE_CONTINUE"); _state = INITIAL_DOPPLER_ESTIMATE_CONTINUE; } - continue; - } - _samples.push_back(in[i++]); - } // INITIAL_DOPPLER_ESTIMATE_CONTINUE + break; + } // INITIAL_DOPPLER_ESTIMATE_CONTINUE - if (_state == INITIAL_DOPPLER_ESTIMATE_CONTINUE) { - GR_LOG_DEBUG(d_logger, "INITIAL_DOPPLER_ESTIMATE_CONTINUE"); - while (!_samples.empty() && nout < noutput_items) { - insert_sample(_samples.back()); - _sample_counter += 1; - _samples.pop_back(); - if ((_sample_counter%_sps) == 0) - out[nout++] = filter(); - } - if (_samples.empty()) { - _state = DO_FILTER; - } else { - _state = INITIAL_DOPPLER_ESTIMATE_CONTINUE; - } - continue; - } // INITIAL_DOPPLER_ESTIMATE_CONTINUE - - if (_state == DO_FILTER) { - if ((_sample_counter%_sps) == 0) { - if (_symbol_counter == _symbols.size()) { // frame is ready - _symbol_counter = 0; - GILLock gil_lock; - try { - // update doppler estimate - update_doppler_information(_physicalLayer.attr("get_doppler") - (complex_vector_to_ndarray(_descrambled_symbols), - complex_vector_to_ndarray(_samples))); - // publish soft decisions - 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(); + case DO_FILTER: { + if ((_sample_counter%_sps) == 0) { + if (_symbol_counter == _symbols.size()) { // frame is ready + _symbol_counter = 0; + GILLock gil_lock; + try { + // update doppler estimate + if (!update_doppler_information(_physicalLayer.attr("get_doppler") + (complex_vector_to_ndarray(_descrambled_symbols), + complex_vector_to_ndarray(_samples)))) { + GR_LOG_DEBUG(d_logger, "next state > WAIT_FOR_PREAMBLE"); + _state = WAIT_FOR_PREAMBLE; + break; + } + // publish soft decisions + 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(); + // get information about the following frame + update_frame_information(_physicalLayer.attr("get_frame")()); + } catch (boost::python::error_already_set const&) { + PyErr_Print(); } - _samples.clear(); - // get information about the following frame - update_frame_information(_physicalLayer.attr("get_frame")()); - } catch (boost::python::error_already_set const&) { - PyErr_Print(); + } // frame is ready + if (_ignore_filter_updates == 0) { + out[nout++] = filter(); + if (_symbol_counter+1 == _symbols.size()) + recenter_filter_taps(); + } else { + _ignore_filter_updates -= 1; } - } // frame is ready - if (_ignore_filter_updates == 0) { - out[nout++] = filter(); - if (_symbol_counter+1 == _symbols.size()) - recenter_filter_taps(); - } else { - _ignore_filter_updates -= 1; + } // (_sample_counter%_sps) == 0 + if (_need_samples) { + _samples.push_back(_hist_samples[_hist_sample_index+_nB+1]); } - } // (_sample_counter%_sps) == 0 - - - if (_need_samples) { - _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; - } // DO_FILTER + if (_saved_samples.empty()) { + insert_sample(in[i++]); + } else { + insert_sample(_saved_samples.back()); + _saved_samples.pop_back(); + } + _sample_counter += 1; + } // DO_FILTER + } // switch _state } // next input sample consume(0, i); @@ -522,7 +533,6 @@ bool adaptive_dfe_impl::update_doppler_information(boost::python::object obj) 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)); diff --git a/python/physical_layer/MIL_STD_188_110C.py b/python/physical_layer/MIL_STD_188_110C.py new file mode 100644 index 0000000..b2a879d --- /dev/null +++ b/python/physical_layer/MIL_STD_188_110C.py @@ -0,0 +1,232 @@ +## -*- python -*- + +from __future__ import print_function +import numpy as np + +def n_psk(n,x): + return np.complex64(np.exp(2j*np.pi*x/n)) + +## ---- constellations ----------------------------------------------------------- +CONST_DTYPE=np.dtype([('points', np.complex64), + ('symbols', np.uint8)]) +BPSK=np.array(zip(np.exp(2j*np.pi*np.arange(2)/2), range(2)), CONST_DTYPE) +QPSK=np.array(zip(np.exp(2j*np.pi*np.arange(4)/4), [0,1,3,2]), CONST_DTYPE) +PSK8=np.array(zip(np.exp(2j*np.pi*np.arange(8)/8), [0,1,3,2,7,6,4,5]), CONST_DTYPE) +QAM16=np.array( + zip([+0.866025+0.500000j, 0.500000+0.866025j, 1.000000+0.000000j, 0.258819+0.258819j, + -0.500000+0.866025j, 0.000000+1.000000j, -0.866025+0.500000j, -0.258819+0.258819j, + +0.500000-0.866025j, 0.000000-1.000000j, 0.866025-0.500000j, 0.258819-0.258819j, + -0.866025-0.500000j, -0.500000-0.866025j, -1.000000+0.000000j, -0.258819-0.258819j], + range(16)), CONST_DTYPE) +QAM32=np.array( + zip([+0.866380+0.499386j, 0.984849+0.173415j, 0.499386+0.866380j, 0.173415+0.984849j, + +0.520246+0.520246j, 0.520246+0.173415j, 0.173415+0.520246j, 0.173415+0.173415j, + -0.866380+0.499386j, -0.984849+0.173415j, -0.499386+0.866380j, -0.173415+0.984849j, + -0.520246+0.520246j, -0.520246+0.173415j, -0.173415+0.520246j, -0.173415+0.173415j, + +0.866380-0.499386j, 0.984849-0.173415j, 0.499386-0.866380j, 0.173415-0.984849j, + +0.520246-0.520246j, 0.520246-0.173415j, 0.173415-0.520246j, 0.173415-0.173415j, + -0.866380-0.499386j, -0.984849-0.173415j, -0.499386-0.866380j, -0.173415-0.984849j, + -0.520246-0.520246j, -0.520246-0.173415j, -0.173415-0.520246j, -0.173415-0.173415j], + range(32)), CONST_DTYPE) +QAM64=np.array( + zip([+1.000000+0.000000j, 0.822878+0.568218j, 0.821137+0.152996j, 0.932897+0.360142j, + +0.000000-1.000000j, 0.822878-0.568218j, 0.821137-0.152996j, 0.932897-0.360142j, + +0.568218+0.822878j, 0.588429+0.588429j, 0.588429+0.117686j, 0.588429+0.353057j, + +0.568218-0.822878j, 0.588429-0.588429j, 0.588429-0.117686j, 0.588429-0.353057j, + +0.152996+0.821137j, 0.117686+0.588429j, 0.117686+0.117686j, 0.117686+0.353057j, + +0.152996-0.821137j, 0.117686-0.588429j, 0.117686-0.117686j, 0.117686-0.353057j, + +0.360142+0.932897j, 0.353057+0.588429j, 0.353057+0.117686j, 0.353057+0.353057j, + +0.360142-0.932897j, 0.353057-0.588429j, 0.353057-0.117686j, 0.353057-0.353057j, + +0.000000+1.000000j, -0.822878+0.568218j, -0.821137+0.152996j, -0.932897+0.360142j, + -1.000000+0.000000j, -0.822878-0.568218j, -0.821137-0.152996j, -0.932897-0.360142j, + -0.568218+0.822878j, -0.588429+0.588429j, -0.588429+0.117686j, -0.588429+0.353057j, + -0.568218-0.822878j, -0.588429-0.588429j, -0.588429-0.117686j, -0.588429-0.353057j, + -0.152996+0.821137j, -0.117686+0.588429j, -0.117686+0.117686j, -0.117686+0.353057j, + -0.152996-0.821137j, -0.117686-0.588429j, -0.117686-0.117686j, -0.117686-0.353057j, + -0.360142+0.932897j, -0.353057+0.588429j, -0.353057+0.117686j, -0.353057+0.353057j, + -0.360142-0.932897j, -0.353057-0.588429j, -0.353057-0.117686j, -0.353057-0.353057j], + range(64)), CONST_DTYPE) + +## ---- constellation indices --------------------------------------------------- +MODE_BPSK = 0 +MODE_QPSK = 1 +MODE_8PSK = 2 +MODE_16QAM = 3 +MODE_32QAM = 4 +MODE_64QAM = 5 + +## ---- data scrambler ----------------------------------------------------------- +class ScrambleData(object): + """data scrambling sequence generator""" + def __init__(self): + self.reset() + + def reset(self): + self._state = 1 + + def next(self, num_bits): + r = self._state & ((1<>1)&511 + if lsb: + self._state ^= 0x10B + return self._state + +## ---- preamble definitions --------------------------------------------------- +## 184 = 8*23 +PREAMBLE=np.array( + [1,5,1,3,6,1,3,1,1,6,3,7,7,3,5,4,3,6,6,4,5,4,0, + 2,2,2,6,0,7,5,7,4,0,7,5,7,1,6,1,0,5,2,2,6,2,3, + 6,0,0,5,1,4,2,2,2,3,4,0,6,2,7,4,3,3,7,2,0,2,6, + 4,4,1,7,6,2,0,6,2,3,6,7,4,3,6,1,3,7,4,6,5,7,2, + 0,1,1,1,4,4,0,0,5,7,7,4,7,3,5,4,1,6,5,6,6,4,6, + 3,4,3,0,7,1,3,4,7,0,1,4,3,3,3,5,1,1,1,4,6,1,0, + 6,0,1,3,1,4,1,7,7,6,3,0,0,7,2,7,2,0,2,6,1,1,1, + 2,7,7,5,3,3,6,0,5,3,3,1,0,7,1,1,0,3,0,4,0,7,3], + dtype=np.uint8) + +## 103 = 31 + 1 + 3*13 + 1 + 31 +REINSERTED_PREAMBLE=np.array( + [0,0,0,0,0,2,4,6,0,4,0,4,0,6,4,2,0,0,0,0,0,2,4,6,0,4,0,4,0,6,4, ## MP+ + 2, + 0,4,0,4,0,0,4,4,0,0,0,0,0, # + D0 + 0,4,0,4,0,0,4,4,0,0,0,0,0, # + D1 + 0,4,0,4,0,0,4,4,0,0,0,0,0, # + D2 + 6, + 4,4,4,4,4,6,0,2,4,0,4,0,4,2,0,6,4,4,4,4,4,6,0,2,4,0,4,0,4,2,0], ## MP- + dtype=np.uint8) + +## ---- physcal layer class ----------------------------------------------------- +class PhysicalLayer(object): + """Physical layer description for MIL-STD-188-110 Appendix D = STANAG 4539""" + + def __init__(self, sps): + """intialization""" + self._sps = sps + self._frame_counter = -1 + self._constellations = [BPSK, QPSK, PSK8, QAM16, QAM32, QAM64] + self._preamble = self.get_preamble() + self._scr_data = ScrambleData() + + def get_constellations(self): + return self._constellations + + def get_frame(self): + """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 + [3] ... a boolean indicating if the soft decision for the unknown + symbols are saved""" + print('-------------------- get_frame --------------------', + self._frame_counter) + ## --- preamble frame ---- + if self._frame_counter == -1: + return [self._preamble,MODE_BPSK,True,False] + ## ----- data frame ------ + if self._frame_counter == 0: + self.a = self.make_reinserted_preamble() + return [self.a, MODE_QPSK,False,True] + + def get_doppler(self, symbols, iq_samples): + """returns a tuple + [0] ... quality flag + [1] ... doppler estimate (rad/symbol) if available""" + print('-------------------- get_doppler --------------------', + self._frame_counter,len(symbols),len(iq_samples)) + #if len(symbols)!=0: + # print('symb=', symbols) + success = False + doppler = 0 + if self._frame_counter == -1: ## -- preamble ---- + success,doppler = self.get_doppler_from_preamble(symbols, iq_samples) + if len(symbols) != 0: + for s in symbols: + print(s) + self._frame_counter = 0 + else: ## ------------------------ data frame ---- + if len(symbols) != 0: + for s in symbols: + print(s) + success = False + self._frame_counter = -1 + return success,doppler + + def get_doppler_from_preamble(self, symbols, iq_samples): + """quality check and doppler estimation for preamble""" + success = True + doppler = 0 + shift=9 + if len(iq_samples) != 0: + zp = np.conj(self.get_preamble_z(self._sps)[shift*self._sps:]) + cc = np.array([np.sum(iq_samples[i:i+23*self._sps] * + zp[0:23*self._sps]) + for i in range(23*3*self._sps)]) + acc = np.abs(cc) + for i in range(0,len(cc),23*self._sps): + print('i=%3d: '%i,end='') + for j in range(23*self._sps): + print('%3.0f ' % acc[i+j], end='') + print() + + imax = np.argmax(np.abs(cc[0:3*23*self._sps])) + print(imax) + pks = np.array([np.sum(iq_samples[(imax+23*i*self._sps): + (imax+23*i*self._sps+23*self._sps)] * + zp[(23*i*self._sps): + (23*i*self._sps+23*self._sps)]) + for i in range(1,5)]) + print('doppler apks', np.abs(pks)) + print('doppler ppks', np.angle(pks), np.diff(np.unwrap(np.angle(pks)))/23) + doppler = np.mean(np.diff(np.unwrap(np.angle(pks))))/23 + success = True + print('success=', success, 'doppler=', doppler) + return success,doppler + + def make_reinserted_preamble(self): + a=np.zeros(len(REINSERTED_PREAMBLE), dtype=[('symb', np.complex64), + ('scramble', np.complex64)]) + a['symb'] = n_psk(8, REINSERTED_PREAMBLE) + a['scramble'] = n_psk(8, REINSERTED_PREAMBLE) + a['symb'][32:32+3*13] = 0 ## D0,D1,D2 + return a + + @staticmethod + def get_preamble(): + """preamble symbols + scrambler""" + a=np.zeros(len(PREAMBLE), dtype=[('symb', np.complex64), + ('scramble', np.complex64)]) + a['symb'] = n_psk(8, PREAMBLE) + a['scramble'] = n_psk(8, PREAMBLE) + ##a['symb'][-30:] = 0 + return a + + @staticmethod + def get_preamble_z(sps): + """preamble symbols for preamble correlation""" + a = PhysicalLayer.get_preamble() + return np.array([z for z in a['symb'] for i in range(sps)]) + +if __name__ == '__main__': + print(PREAMBLE) + z = n_psk(8,PREAMBLE) + cc = [np.sum(z[0:23]*np.conj(z[23*i:23*i+23])) for i in range(6)] + print(np.abs(cc)) + print(np.angle(cc)/np.pi*4) + print(all(z==PhysicalLayer.get_preamble()['symb'])) + print(len(PhysicalLayer.get_preamble()['symb'])) + s = ScrambleData() + print([s.next(1) for _ in range(511)]) + print([s.next(1) for _ in range(511)] == + [s.next(1) for _ in range(511)]) + print(QAM64) + print(QAM32) + print(QAM16) + print(PSK8) + print(QPSK) + print(BPSK)