mirror of
https://github.com/hb9fxq/gr-digitalhf
synced 2024-12-21 23:09:59 +00:00
doppler correction separated from adaptive filtering
* pulse filter, preamble detection, doppler correction, and adaptive filter combined into one hier block
This commit is contained in:
parent
9298637d69
commit
d25b06a9d7
|
@ -96,7 +96,7 @@ set(Boost_ADDITIONAL_VERSIONS
|
|||
"1.60.0" "1.60" "1.61.0" "1.61" "1.62.0" "1.62" "1.63.0" "1.63" "1.64.0" "1.64"
|
||||
"1.65.0" "1.65" "1.66.0" "1.66" "1.67.0" "1.67" "1.68.0" "1.68" "1.69.0" "1.69"
|
||||
)
|
||||
find_package(Boost "1.35" COMPONENTS filesystem system python numpy)
|
||||
find_package(Boost "1.35" COMPONENTS filesystem system)
|
||||
|
||||
if(NOT Boost_FOUND)
|
||||
message(FATAL_ERROR "Boost required to compile digitalhf")
|
||||
|
@ -178,7 +178,6 @@ include_directories(
|
|||
${CMAKE_SOURCE_DIR}/include
|
||||
${CMAKE_BINARY_DIR}/lib
|
||||
${CMAKE_BINARY_DIR}/include
|
||||
${PYTHON_INCLUDE_DIR}
|
||||
${Boost_INCLUDE_DIRS}
|
||||
${CPPUNIT_INCLUDE_DIRS}
|
||||
${GNURADIO_ALL_INCLUDE_DIRS}
|
||||
|
|
|
@ -109,7 +109,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(1141, 80)</value>
|
||||
<value>(810, 16)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>gui_hint</key>
|
||||
|
@ -156,33 +156,6 @@
|
|||
<value>counter_slider</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>variable</key>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(320, 16)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>lpz</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>value</key>
|
||||
<value>MIL_STD_188_110A.PhysicalLayer.get_preamble_z(sps).tolist()</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>variable_qtgui_range</key>
|
||||
<param>
|
||||
|
@ -199,7 +172,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(1024, 80)</value>
|
||||
<value>(682, 16)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>gui_hint</key>
|
||||
|
@ -258,7 +231,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(533, 16)</value>
|
||||
<value>(405, 16)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
|
@ -285,7 +258,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(608, 16)</value>
|
||||
<value>(480, 16)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
|
@ -312,7 +285,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(682, 16)</value>
|
||||
<value>(565, 16)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
|
@ -327,49 +300,6 @@
|
|||
<value>4</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>variable_rrc_filter_taps</key>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>1</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>alpha</key>
|
||||
<value>0.35</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>
|
||||
<key>variable</key>
|
||||
<param>
|
||||
|
@ -409,7 +339,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(458, 16)</value>
|
||||
<value>(320, 16)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
|
@ -424,6 +354,69 @@
|
|||
<value>5</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>analog_agc2_xx</key>
|
||||
<param>
|
||||
<key>attack_rate</key>
|
||||
<value>1e-1</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>affinity</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>decay_rate</key>
|
||||
<value>1e-2</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>1</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(458, 154)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>gain</key>
|
||||
<value>5</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>analog_agc2_xx_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>max_gain</key>
|
||||
<value>8</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>minoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>reference</key>
|
||||
<value>1.0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>type</key>
|
||||
<value>complex</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>blocks_complex_to_mag</key>
|
||||
<param>
|
||||
|
@ -444,11 +437,11 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(928, 314)</value>
|
||||
<value>(426, 368)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
<value>180</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
|
@ -483,7 +476,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
<value>1</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
|
@ -510,57 +503,6 @@
|
|||
<value>1</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>blocks_multiply_const_vxx</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>const</key>
|
||||
<value>5</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>affinity</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(426, 176)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>blocks_multiply_const_vxx_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>type</key>
|
||||
<value>complex</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>minoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>vlen</key>
|
||||
<value>1</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>blocks_tag_debug</key>
|
||||
<param>
|
||||
|
@ -585,7 +527,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(917, 133)</value>
|
||||
<value>(1002, 282)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
|
@ -636,7 +578,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(586, 176)</value>
|
||||
<value>(672, 176)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
|
@ -687,7 +629,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
<value>1</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>file</key>
|
||||
|
@ -719,11 +661,11 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>repeat</key>
|
||||
<value>False</value>
|
||||
<value>True</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>digitalhf_adaptive_dfe</key>
|
||||
<key>digitalhf_physical_layer_driver</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
|
@ -736,21 +678,25 @@
|
|||
<key>affinity</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>description_name</key>
|
||||
<value>MIL_STD_188_110A</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
<value>1</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(874, 389)</value>
|
||||
<value>(661, 325)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
<value>180</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>digitalhf_adaptive_dfe_0</value>
|
||||
<value>digitalhf_physical_layer_driver_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
|
@ -766,11 +712,11 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>alpha</key>
|
||||
<value>0.0005</value>
|
||||
<value>0.005</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>mode</key>
|
||||
<value>''</value>
|
||||
<value>""</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>mu</key>
|
||||
|
@ -789,215 +735,8 @@
|
|||
<value>nW</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>py_obj_name</key>
|
||||
<value>MIL_STD_188_110A</value>
|
||||
</param>
|
||||
</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>1</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>import</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(1034, 21)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>import_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>import</key>
|
||||
<value>import digitalhf.physical_layer.MIL_STD_188_110A as MIL_STD_188_110A</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>import</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(960, 21)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>import_0_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>import</key>
|
||||
<value>from gnuradio import gr</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>import</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(810, 32)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>import_1</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>import</key>
|
||||
<value>import numpy as np</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>digital_corr_est_cc</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>(640, 272)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>preamble</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>minoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>sps</key>
|
||||
<value>sps</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>symbols</key>
|
||||
<value>lpz</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>mark_delay</key>
|
||||
<value>nF*sps-2</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>threshold_method</key>
|
||||
<value>digital.corr_est_cc.THRESHOLD_DYNAMIC</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>threshold</key>
|
||||
<value>0.35</value>
|
||||
<key>samp_rate</key>
|
||||
<value>samp_rate</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
|
@ -1028,7 +767,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(1109, 410)</value>
|
||||
<value>(394, 464)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>gui_hint</key>
|
||||
|
@ -1036,7 +775,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
<value>180</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>grid</key>
|
||||
|
@ -1383,7 +1122,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(1120, 304)</value>
|
||||
<value>(181, 357)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>gui_hint</key>
|
||||
|
@ -1391,7 +1130,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
<value>180</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>grid</key>
|
||||
|
@ -1746,11 +1485,11 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
<value>1</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(1002, 602)</value>
|
||||
<value>(426, 293)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>gui_hint</key>
|
||||
|
@ -1758,7 +1497,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
<value>180</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>grid</key>
|
||||
|
@ -2117,7 +1856,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(1120, 218)</value>
|
||||
<value>(938, 165)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>gui_hint</key>
|
||||
|
@ -2304,6 +2043,12 @@
|
|||
<value>firdes.WIN_BLACKMAN_hARRIS</value>
|
||||
</param>
|
||||
</block>
|
||||
<connection>
|
||||
<source_block_id>analog_agc2_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>
|
||||
<source_block_id>blocks_complex_to_mag_0</source_block_id>
|
||||
<sink_block_id>qtgui_time_sink_x_0</sink_block_id>
|
||||
|
@ -2312,19 +2057,19 @@
|
|||
</connection>
|
||||
<connection>
|
||||
<source_block_id>blocks_float_to_complex_0</source_block_id>
|
||||
<sink_block_id>blocks_multiply_const_vxx_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>blocks_multiply_const_vxx_0</source_block_id>
|
||||
<sink_block_id>blocks_throttle_0</sink_block_id>
|
||||
<sink_block_id>analog_agc2_xx_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>blocks_throttle_0</source_block_id>
|
||||
<sink_block_id>fir_filter_xxx_0</sink_block_id>
|
||||
<sink_block_id>digitalhf_physical_layer_driver_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>blocks_throttle_0</source_block_id>
|
||||
<sink_block_id>qtgui_waterfall_sink_x_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
|
@ -2341,45 +2086,21 @@
|
|||
<sink_key>1</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>digitalhf_adaptive_dfe_0</source_block_id>
|
||||
<sink_block_id>qtgui_const_sink_x_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</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>
|
||||
<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>preamble</source_block_id>
|
||||
<source_block_id>digitalhf_physical_layer_driver_0</source_block_id>
|
||||
<sink_block_id>blocks_complex_to_mag_0</sink_block_id>
|
||||
<source_key>1</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>preamble</source_block_id>
|
||||
<sink_block_id>blocks_tag_debug_0</sink_block_id>
|
||||
<source_block_id>digitalhf_physical_layer_driver_0</source_block_id>
|
||||
<sink_block_id>qtgui_const_sink_x_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>preamble</source_block_id>
|
||||
<sink_block_id>digitalhf_adaptive_dfe_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>preamble</source_block_id>
|
||||
<sink_block_id>qtgui_waterfall_sink_x_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
<source_block_id>digitalhf_physical_layer_driver_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>
|
||||
</flow_graph>
|
||||
|
|
|
@ -109,7 +109,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(1141, 80)</value>
|
||||
<value>(1141, 240)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>gui_hint</key>
|
||||
|
@ -156,33 +156,6 @@
|
|||
<value>counter_slider</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>variable</key>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(320, 16)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>lpz</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>value</key>
|
||||
<value>MIL_STD_188_110C.PhysicalLayer.get_preamble_z(sps).tolist()</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>variable_qtgui_range</key>
|
||||
<param>
|
||||
|
@ -199,7 +172,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(1024, 80)</value>
|
||||
<value>(629, 16)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>gui_hint</key>
|
||||
|
@ -258,7 +231,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(533, 16)</value>
|
||||
<value>(416, 16)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
|
@ -285,7 +258,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(608, 16)</value>
|
||||
<value>(480, 16)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
|
@ -312,7 +285,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(682, 16)</value>
|
||||
<value>(554, 16)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
|
@ -327,49 +300,6 @@
|
|||
<value>4</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>variable_rrc_filter_taps</key>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>1</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>alpha</key>
|
||||
<value>0.35</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>
|
||||
<key>variable</key>
|
||||
<param>
|
||||
|
@ -409,7 +339,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(458, 16)</value>
|
||||
<value>(330, 16)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
|
@ -424,6 +354,69 @@
|
|||
<value>5</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>analog_agc2_xx</key>
|
||||
<param>
|
||||
<key>attack_rate</key>
|
||||
<value>.1</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>affinity</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>decay_rate</key>
|
||||
<value>.01</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>1</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(448, 133)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>gain</key>
|
||||
<value>5</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>analog_agc2_xx_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>max_gain</key>
|
||||
<value>8</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>minoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>reference</key>
|
||||
<value>1.0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>type</key>
|
||||
<value>complex</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>blocks_complex_to_mag</key>
|
||||
<param>
|
||||
|
@ -444,11 +437,11 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(928, 314)</value>
|
||||
<value>(576, 453)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
<value>180</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
|
@ -487,7 +480,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
<value>1</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>file</key>
|
||||
|
@ -495,11 +488,11 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(693, 677)</value>
|
||||
<value>(277, 293)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
<value>180</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
|
@ -534,11 +527,11 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
<value>1</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(256, 154)</value>
|
||||
<value>(256, 133)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
|
@ -561,57 +554,6 @@
|
|||
<value>1</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>blocks_multiply_const_vxx</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>const</key>
|
||||
<value>5</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>affinity</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(426, 176)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>blocks_multiply_const_vxx_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>type</key>
|
||||
<value>complex</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>minoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>vlen</key>
|
||||
<value>1</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>blocks_pdu_to_tagged_stream</key>
|
||||
<param>
|
||||
|
@ -628,15 +570,15 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
<value>1</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(458, 581)</value>
|
||||
<value>(544, 368)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
<value>180</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
|
@ -683,7 +625,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(917, 133)</value>
|
||||
<value>(1162, 421)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
|
@ -734,7 +676,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(586, 176)</value>
|
||||
<value>(661, 154)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
|
@ -785,7 +727,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
<value>1</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>file</key>
|
||||
|
@ -793,7 +735,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(10, 154)</value>
|
||||
<value>(10, 133)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
|
@ -817,11 +759,11 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>repeat</key>
|
||||
<value>True</value>
|
||||
<value>False</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>digitalhf_adaptive_dfe</key>
|
||||
<key>digitalhf_physical_layer_driver</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
|
@ -834,21 +776,25 @@
|
|||
<key>affinity</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>description_name</key>
|
||||
<value>MIL_STD_188_110C</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(874, 389)</value>
|
||||
<value>(821, 400)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
<value>180</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>digitalhf_adaptive_dfe_0</value>
|
||||
<value>digitalhf_physical_layer_driver_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
|
@ -864,11 +810,11 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>alpha</key>
|
||||
<value>0.0001</value>
|
||||
<value>0.005</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>mode</key>
|
||||
<value>''</value>
|
||||
<value>""</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>mu</key>
|
||||
|
@ -887,215 +833,8 @@
|
|||
<value>nW</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>py_obj_name</key>
|
||||
<value>MIL_STD_188_110C</value>
|
||||
</param>
|
||||
</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>1</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>import</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(1034, 21)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>import_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>import</key>
|
||||
<value>import digitalhf.physical_layer.MIL_STD_188_110C as MIL_STD_188_110C</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>import</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(960, 21)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>import_0_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>import</key>
|
||||
<value>from gnuradio import gr</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>import</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(810, 32)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>import_1</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>import</key>
|
||||
<value>import numpy as np</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>digital_corr_est_cc</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>(640, 272)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>preamble</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>minoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>sps</key>
|
||||
<value>sps</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>symbols</key>
|
||||
<value>lpz</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>mark_delay</key>
|
||||
<value>nF*sps-2</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>threshold_method</key>
|
||||
<value>digital.corr_est_cc.THRESHOLD_DYNAMIC</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>threshold</key>
|
||||
<value>0.5</value>
|
||||
<key>samp_rate</key>
|
||||
<value>samp_rate</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
|
@ -1126,7 +865,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(1109, 410)</value>
|
||||
<value>(554, 538)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>gui_hint</key>
|
||||
|
@ -1134,7 +873,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
<value>180</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>grid</key>
|
||||
|
@ -1481,7 +1220,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(1120, 304)</value>
|
||||
<value>(288, 474)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>gui_hint</key>
|
||||
|
@ -1489,7 +1228,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
<value>180</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>grid</key>
|
||||
|
@ -1844,11 +1583,11 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
<value>1</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(1002, 602)</value>
|
||||
<value>(298, 378)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>gui_hint</key>
|
||||
|
@ -1856,7 +1595,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
<value>180</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>grid</key>
|
||||
|
@ -2215,7 +1954,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(1120, 218)</value>
|
||||
<value>(1066, 101)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>gui_hint</key>
|
||||
|
@ -2402,6 +2141,12 @@
|
|||
<value>firdes.WIN_BLACKMAN_hARRIS</value>
|
||||
</param>
|
||||
</block>
|
||||
<connection>
|
||||
<source_block_id>analog_agc2_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>
|
||||
<source_block_id>blocks_complex_to_mag_0</source_block_id>
|
||||
<sink_block_id>qtgui_time_sink_x_0</sink_block_id>
|
||||
|
@ -2410,13 +2155,7 @@
|
|||
</connection>
|
||||
<connection>
|
||||
<source_block_id>blocks_float_to_complex_0</source_block_id>
|
||||
<sink_block_id>blocks_multiply_const_vxx_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>blocks_multiply_const_vxx_0</source_block_id>
|
||||
<sink_block_id>blocks_throttle_0</sink_block_id>
|
||||
<sink_block_id>analog_agc2_xx_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
|
@ -2434,7 +2173,13 @@
|
|||
</connection>
|
||||
<connection>
|
||||
<source_block_id>blocks_throttle_0</source_block_id>
|
||||
<sink_block_id>fir_filter_xxx_0</sink_block_id>
|
||||
<sink_block_id>digitalhf_physical_layer_driver_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>blocks_throttle_0</source_block_id>
|
||||
<sink_block_id>qtgui_waterfall_sink_x_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
|
@ -2451,45 +2196,21 @@
|
|||
<sink_key>1</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>digitalhf_adaptive_dfe_0</source_block_id>
|
||||
<sink_block_id>qtgui_const_sink_x_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>digitalhf_adaptive_dfe_0</source_block_id>
|
||||
<sink_block_id>blocks_pdu_to_tagged_stream_0</sink_block_id>
|
||||
<source_key>soft_dec</source_key>
|
||||
<sink_key>pdus</sink_key>
|
||||
</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>preamble</source_block_id>
|
||||
<source_block_id>digitalhf_physical_layer_driver_0</source_block_id>
|
||||
<sink_block_id>blocks_complex_to_mag_0</sink_block_id>
|
||||
<source_key>1</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>preamble</source_block_id>
|
||||
<sink_block_id>blocks_tag_debug_0</sink_block_id>
|
||||
<source_block_id>digitalhf_physical_layer_driver_0</source_block_id>
|
||||
<sink_block_id>qtgui_const_sink_x_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>preamble</source_block_id>
|
||||
<sink_block_id>digitalhf_adaptive_dfe_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>preamble</source_block_id>
|
||||
<sink_block_id>qtgui_waterfall_sink_x_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
<source_block_id>digitalhf_physical_layer_driver_0</source_block_id>
|
||||
<sink_block_id>blocks_pdu_to_tagged_stream_0</sink_block_id>
|
||||
<source_key>soft_dec</source_key>
|
||||
<sink_key>pdus</sink_key>
|
||||
</connection>
|
||||
</flow_graph>
|
||||
|
|
|
@ -93,33 +93,6 @@
|
|||
<value>(0,0)</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>variable</key>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(757, 16)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>dummy</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>value</key>
|
||||
<value>[lpz[0].extend(x) for x in lpz[1:]]</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>variable_qtgui_range</key>
|
||||
<param>
|
||||
|
@ -136,7 +109,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(1141, 80)</value>
|
||||
<value>(1141, 16)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>gui_hint</key>
|
||||
|
@ -183,33 +156,6 @@
|
|||
<value>counter_slider</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>variable</key>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(320, 16)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>lpz</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>value</key>
|
||||
<value>[[x,x,x,x,x] for x in STANAG_4285.PhysicalLayer.get_preamble()['symb'][9:40].tolist()]</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>variable_qtgui_chooser</key>
|
||||
<param>
|
||||
|
@ -226,7 +172,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(1152, 490)</value>
|
||||
<value>(1152, 277)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>gui_hint</key>
|
||||
|
@ -325,7 +271,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(1024, 80)</value>
|
||||
<value>(1152, 144)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>gui_hint</key>
|
||||
|
@ -384,7 +330,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(533, 16)</value>
|
||||
<value>(394, 16)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
|
@ -411,7 +357,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(608, 16)</value>
|
||||
<value>(469, 16)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
|
@ -438,7 +384,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(682, 16)</value>
|
||||
<value>(544, 16)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
|
@ -453,49 +399,6 @@
|
|||
<value>4</value>
|
||||
</param>
|
||||
</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>
|
||||
<key>variable</key>
|
||||
<param>
|
||||
|
@ -535,7 +438,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(458, 16)</value>
|
||||
<value>(320, 16)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
|
@ -550,6 +453,69 @@
|
|||
<value>5</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>analog_agc2_xx</key>
|
||||
<param>
|
||||
<key>attack_rate</key>
|
||||
<value>1e-1</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>affinity</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>decay_rate</key>
|
||||
<value>1e-2</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>1</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(480, 154)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>gain</key>
|
||||
<value>5</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>analog_agc2_xx_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>max_gain</key>
|
||||
<value>8</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>minoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>reference</key>
|
||||
<value>1.0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>type</key>
|
||||
<value>complex</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>blocks_complex_to_mag</key>
|
||||
<param>
|
||||
|
@ -570,11 +536,11 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(928, 314)</value>
|
||||
<value>(533, 368)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
<value>180</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
|
@ -613,7 +579,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(256, 154)</value>
|
||||
<value>(277, 154)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
|
@ -636,57 +602,6 @@
|
|||
<value>1</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>blocks_multiply_const_vxx</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>const</key>
|
||||
<value>5</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>affinity</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(426, 176)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>blocks_multiply_const_vxx_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>type</key>
|
||||
<value>complex</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>minoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>vlen</key>
|
||||
<value>1</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>blocks_tag_debug</key>
|
||||
<param>
|
||||
|
@ -711,7 +626,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(917, 133)</value>
|
||||
<value>(1184, 464)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
|
@ -762,7 +677,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(586, 176)</value>
|
||||
<value>(682, 176)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
|
@ -817,7 +732,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>file</key>
|
||||
<value>/Users/chm/Downloads/kiwi-sm2gct.mooo.com_2018-10-30T10_35_39Z_8700.00_iq.wav</value>
|
||||
<value>/Users/chm/Software/signal-analysis/gnuradio/20181027T095433Z_6407800_SM2GCT_iq.wav</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
|
@ -845,11 +760,11 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>repeat</key>
|
||||
<value>False</value>
|
||||
<value>True</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>digitalhf_adaptive_dfe</key>
|
||||
<key>digitalhf_physical_layer_driver</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
|
@ -862,21 +777,25 @@
|
|||
<key>affinity</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>description_name</key>
|
||||
<value>STANAG_4285</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(874, 389)</value>
|
||||
<value>(736, 314)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
<value>180</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>digitalhf_adaptive_dfe_0</value>
|
||||
<value>digitalhf_physical_layer_driver_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
|
@ -915,235 +834,8 @@
|
|||
<value>nW</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>py_obj_name</key>
|
||||
<value>STANAG_4285</value>
|
||||
</param>
|
||||
</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>
|
||||
<key>import</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(1034, 21)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>import_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>import</key>
|
||||
<value>import digitalhf.physical_layer.STANAG_4285 as STANAG_4285</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>import</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(960, 21)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>import_0_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>import</key>
|
||||
<value>from gnuradio import gr</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>digital_corr_est_cc</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>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(640, 272)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>preamble</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>minoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>sps</key>
|
||||
<value>sps</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>symbols</key>
|
||||
<value>lpz[0]</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>mark_delay</key>
|
||||
<value>(nF-9)*sps+2</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>threshold_method</key>
|
||||
<value>digital.corr_est_cc.THRESHOLD_DYNAMIC</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>threshold</key>
|
||||
<value>0.5</value>
|
||||
<key>samp_rate</key>
|
||||
<value>samp_rate</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
|
@ -1174,7 +866,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(1109, 410)</value>
|
||||
<value>(320, 442)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>gui_hint</key>
|
||||
|
@ -1182,7 +874,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
<value>180</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>grid</key>
|
||||
|
@ -1529,7 +1221,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(1120, 304)</value>
|
||||
<value>(320, 357)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>gui_hint</key>
|
||||
|
@ -1537,7 +1229,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
<value>180</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>grid</key>
|
||||
|
@ -1801,7 +1493,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>size</key>
|
||||
<value>1024/2</value>
|
||||
<value>80*sps</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>srate</key>
|
||||
|
@ -1817,7 +1509,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>tr_delay</key>
|
||||
<value>0.01</value>
|
||||
<value>0.007</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>tr_level</key>
|
||||
|
@ -1896,7 +1588,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(1002, 602)</value>
|
||||
<value>(320, 293)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>gui_hint</key>
|
||||
|
@ -1904,7 +1596,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
<value>180</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>grid</key>
|
||||
|
@ -2263,7 +1955,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(1120, 218)</value>
|
||||
<value>(896, 101)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>gui_hint</key>
|
||||
|
@ -2450,6 +2142,12 @@
|
|||
<value>firdes.WIN_BLACKMAN_hARRIS</value>
|
||||
</param>
|
||||
</block>
|
||||
<connection>
|
||||
<source_block_id>analog_agc2_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>
|
||||
<source_block_id>blocks_complex_to_mag_0</source_block_id>
|
||||
<sink_block_id>qtgui_time_sink_x_0</sink_block_id>
|
||||
|
@ -2458,19 +2156,19 @@
|
|||
</connection>
|
||||
<connection>
|
||||
<source_block_id>blocks_float_to_complex_0</source_block_id>
|
||||
<sink_block_id>blocks_multiply_const_vxx_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>blocks_multiply_const_vxx_0</source_block_id>
|
||||
<sink_block_id>fractional_resampler_xx_0</sink_block_id>
|
||||
<sink_block_id>analog_agc2_xx_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>blocks_throttle_0</source_block_id>
|
||||
<sink_block_id>fir_filter_xxx_0</sink_block_id>
|
||||
<sink_block_id>digitalhf_physical_layer_driver_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>blocks_throttle_0</source_block_id>
|
||||
<sink_block_id>qtgui_waterfall_sink_x_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
|
@ -2487,51 +2185,21 @@
|
|||
<sink_key>1</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>digitalhf_adaptive_dfe_0</source_block_id>
|
||||
<sink_block_id>qtgui_const_sink_x_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</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>
|
||||
<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>
|
||||
<source_block_id>preamble</source_block_id>
|
||||
<source_block_id>digitalhf_physical_layer_driver_0</source_block_id>
|
||||
<sink_block_id>blocks_complex_to_mag_0</sink_block_id>
|
||||
<source_key>1</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>preamble</source_block_id>
|
||||
<sink_block_id>blocks_tag_debug_0</sink_block_id>
|
||||
<source_block_id>digitalhf_physical_layer_driver_0</source_block_id>
|
||||
<sink_block_id>qtgui_const_sink_x_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>preamble</source_block_id>
|
||||
<sink_block_id>digitalhf_adaptive_dfe_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>preamble</source_block_id>
|
||||
<sink_block_id>qtgui_waterfall_sink_x_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
<source_block_id>digitalhf_physical_layer_driver_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>
|
||||
</flow_graph>
|
||||
|
|
|
@ -18,5 +18,8 @@
|
|||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
install(FILES
|
||||
digitalhf_adaptive_dfe.xml DESTINATION share/gnuradio/grc/blocks
|
||||
digitalhf_adaptive_dfe.xml
|
||||
digitalhf_physical_layer_driver.xml
|
||||
digitalhf_doppler_correction_cc.xml
|
||||
digitalhf_msg_proxy.xml DESTINATION share/gnuradio/grc/blocks
|
||||
)
|
||||
|
|
|
@ -4,9 +4,8 @@
|
|||
<key>digitalhf_adaptive_dfe</key>
|
||||
<category>[digitalhf]</category>
|
||||
<import>import digitalhf</import>
|
||||
<make>digitalhf.adaptive_dfe($sps,$nB,$nF,$nW,$mu,$alpha,$py_obj_name)</make>
|
||||
<make>digitalhf.adaptive_dfe($sps,$nB,$nF,$nW,$mu,$alpha)</make>
|
||||
<callback>set_mu($mu)</callback>
|
||||
<callback>set_mode($mode)</callback>
|
||||
<!-- Make one 'param' node for every Parameter you want settable from the GUI.
|
||||
Sub-nodes:
|
||||
* name
|
||||
|
@ -42,16 +41,6 @@
|
|||
<key>alpha</key>
|
||||
<type>float</type>
|
||||
</param>
|
||||
<param>
|
||||
<name>py_obj_name</name>
|
||||
<key>py_obj_name</key>
|
||||
<type>string</type>
|
||||
</param>
|
||||
<param>
|
||||
<name>mode</name>
|
||||
<key>mode</key>
|
||||
<type>string</type>
|
||||
</param>
|
||||
|
||||
<!-- Make one 'sink' node per input. Sub-nodes:
|
||||
* name (an identifier for the GUI)
|
||||
|
|
38
grc/digitalhf_doppler_correction_cc.xml
Normal file
38
grc/digitalhf_doppler_correction_cc.xml
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0"?>
|
||||
<block>
|
||||
<name>doppler_correction_cc</name>
|
||||
<key>digitalhf_doppler_correction_cc</key>
|
||||
<category>[digitalhf]</category>
|
||||
<import>import digitalhf</import>
|
||||
<make>digitalhf.doppler_correction_cc($length)</make>
|
||||
<!-- Make one 'param' node for every Parameter you want settable from the GUI.
|
||||
Sub-nodes:
|
||||
* name
|
||||
* key (makes the value accessible as $keyname, e.g. in the make node)
|
||||
* type -->
|
||||
<param>
|
||||
<name>...</name>
|
||||
<key>...</key>
|
||||
<type>...</type>
|
||||
</param>
|
||||
|
||||
<!-- Make one 'sink' node per input. Sub-nodes:
|
||||
* name (an identifier for the GUI)
|
||||
* type
|
||||
* vlen
|
||||
* optional (set to 1 for optional inputs) -->
|
||||
<sink>
|
||||
<name>in</name>
|
||||
<type><!-- e.g. int, float, complex, byte, short, xxx_vector, ...--></type>
|
||||
</sink>
|
||||
|
||||
<!-- Make one 'source' node per output. Sub-nodes:
|
||||
* name (an identifier for the GUI)
|
||||
* type
|
||||
* vlen
|
||||
* optional (set to 1 for optional inputs) -->
|
||||
<source>
|
||||
<name>out</name>
|
||||
<type><!-- e.g. int, float, complex, byte, short, xxx_vector, ...--></type>
|
||||
</source>
|
||||
</block>
|
38
grc/digitalhf_msg_proxy.xml
Normal file
38
grc/digitalhf_msg_proxy.xml
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0"?>
|
||||
<block>
|
||||
<name>msg_proxy</name>
|
||||
<key>digitalhf_msg_proxy</key>
|
||||
<category>[digitalhf]</category>
|
||||
<import>import digitalhf</import>
|
||||
<make>digitalhf.msg_proxy($physical_layer_object)</make>
|
||||
<!-- Make one 'param' node for every Parameter you want settable from the GUI.
|
||||
Sub-nodes:
|
||||
* name
|
||||
* key (makes the value accessible as $keyname, e.g. in the make node)
|
||||
* type -->
|
||||
<param>
|
||||
<name>...</name>
|
||||
<key>...</key>
|
||||
<type>...</type>
|
||||
</param>
|
||||
|
||||
<!-- Make one 'sink' node per input. Sub-nodes:
|
||||
* name (an identifier for the GUI)
|
||||
* type
|
||||
* vlen
|
||||
* optional (set to 1 for optional inputs) -->
|
||||
<sink>
|
||||
<name>in</name>
|
||||
<type><!-- e.g. int, float, complex, byte, short, xxx_vector, ...--></type>
|
||||
</sink>
|
||||
|
||||
<!-- Make one 'source' node per output. Sub-nodes:
|
||||
* name (an identifier for the GUI)
|
||||
* type
|
||||
* vlen
|
||||
* optional (set to 1 for optional inputs) -->
|
||||
<source>
|
||||
<name>out</name>
|
||||
<type><!-- e.g. int, float, complex, byte, short, xxx_vector, ...--></type>
|
||||
</source>
|
||||
</block>
|
76
grc/digitalhf_physical_layer_driver.xml
Normal file
76
grc/digitalhf_physical_layer_driver.xml
Normal file
|
@ -0,0 +1,76 @@
|
|||
<?xml version="1.0"?>
|
||||
<block>
|
||||
<name>physical_layer_driver</name>
|
||||
<key>digitalhf_physical_layer_driver</key>
|
||||
<category>[digitalhf]</category>
|
||||
<import>import digitalhf</import>
|
||||
<make>digitalhf.physical_layer_driver($samp_rate, $sps, $alpha, $mu, $nB, $nF, $nW, $description_name, $mode)</make>
|
||||
<callback>set_mu($mu)</callback>
|
||||
<callback>set_alpha($alpha)</callback>
|
||||
<callback>set_mode($mode)</callback>
|
||||
<param>
|
||||
<name>Description</name>
|
||||
<key>description_name</key>
|
||||
<type>string</type>
|
||||
</param>
|
||||
<param>
|
||||
<name>sample rate</name>
|
||||
<key>samp_rate</key>
|
||||
<type>int</type>
|
||||
</param>
|
||||
<param>
|
||||
<name>SPS</name>
|
||||
<key>sps</key>
|
||||
<type>int</type>
|
||||
</param>
|
||||
<param>
|
||||
<name>nB</name>
|
||||
<key>nB</key>
|
||||
<type>int</type>
|
||||
</param>
|
||||
<param>
|
||||
<name>nF</name>
|
||||
<key>nF</key>
|
||||
<type>int</type>
|
||||
</param>
|
||||
<param>
|
||||
<name>nW</name>
|
||||
<key>nW</key>
|
||||
<type>int</type>
|
||||
</param>
|
||||
<param>
|
||||
<name>mu</name>
|
||||
<key>mu</key>
|
||||
<type>float</type>
|
||||
</param>
|
||||
<param>
|
||||
<name>alpha</name>
|
||||
<key>alpha</key>
|
||||
<type>float</type>
|
||||
</param>
|
||||
<param>
|
||||
<name>mode</name>
|
||||
<key>mode</key>
|
||||
<type>string</type>
|
||||
</param>
|
||||
|
||||
<sink>
|
||||
<name>in</name>
|
||||
<type>complex</type>
|
||||
</sink>
|
||||
|
||||
<source>
|
||||
<name>out_symb</name>
|
||||
<type>complex</type>
|
||||
</source>
|
||||
<source>
|
||||
<name>out_cc</name>
|
||||
<type>complex</type>
|
||||
</source>
|
||||
|
||||
<source>
|
||||
<name>soft_dec</name>
|
||||
<type>message</type>
|
||||
<optional>1</optional>
|
||||
</source>
|
||||
</block>
|
|
@ -23,5 +23,6 @@
|
|||
########################################################################
|
||||
install(FILES
|
||||
api.h
|
||||
adaptive_dfe.h DESTINATION include/digitalhf
|
||||
adaptive_dfe.h
|
||||
doppler_correction_cc.h DESTINATION include/digitalhf
|
||||
)
|
||||
|
|
|
@ -50,13 +50,12 @@ class DIGITALHF_API adaptive_dfe : virtual public gr::block
|
|||
static sptr make(int sps, // samples per symbol
|
||||
int nB, // number of forward FIR taps
|
||||
int nF, // number of backward FIR taps
|
||||
int nW, // number of feedback taps
|
||||
float mu, //
|
||||
float alpha, //
|
||||
std::string physical_layer_description);
|
||||
int nW, // number of feedback symbol taps
|
||||
float mu, // mu - decision-feedback equalizer
|
||||
float alpha); // alpha - decision-feedback equalizer
|
||||
|
||||
virtual void set_mu(float) = 0;
|
||||
virtual void set_mode(std::string) = 0;
|
||||
virtual void set_alpha(float) = 0;
|
||||
} ;
|
||||
|
||||
} // namespace digitalhf
|
||||
|
|
58
include/digitalhf/doppler_correction_cc.h
Normal file
58
include/digitalhf/doppler_correction_cc.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2018 hcab14@gmail.com.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef INCLUDED_DIGITALHF_DOPPLER_CORRECTION_CC_H
|
||||
#define INCLUDED_DIGITALHF_DOPPLER_CORRECTION_CC_H
|
||||
|
||||
#include <digitalhf/api.h>
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
||||
namespace gr {
|
||||
namespace digitalhf {
|
||||
|
||||
/*!
|
||||
* \brief <+description of block+>
|
||||
* \ingroup digitalhf
|
||||
*
|
||||
*/
|
||||
class DIGITALHF_API doppler_correction_cc : virtual public gr::sync_block
|
||||
{
|
||||
public:
|
||||
typedef boost::shared_ptr<doppler_correction_cc> sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of digitalhf::doppler_correction_cc.
|
||||
*
|
||||
* To avoid accidental use of raw pointers, digitalhf::doppler_correction_cc's
|
||||
* constructor is in a private implementation
|
||||
* class. digitalhf::doppler_correction_cc::make is the public interface for
|
||||
* creating new instances.
|
||||
*/
|
||||
static sptr make(unsigned int preamble_length,
|
||||
unsigned int preamble_length_cc);
|
||||
|
||||
};
|
||||
|
||||
} // namespace digitalhf
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_DIGITALHF_DOPPLER_CORRECTION_CC_H */
|
||||
|
|
@ -26,7 +26,8 @@ include(GrPlatform) #define LIB_SUFFIX
|
|||
include_directories(${Boost_INCLUDE_DIR})
|
||||
link_directories(${Boost_LIBRARY_DIRS})
|
||||
list(APPEND digitalhf_sources
|
||||
adaptive_dfe_impl.cc )
|
||||
adaptive_dfe_impl.cc
|
||||
doppler_correction_cc_impl.cc )
|
||||
|
||||
set(digitalhf_sources "${digitalhf_sources}" PARENT_SCOPE)
|
||||
if(NOT digitalhf_sources)
|
||||
|
@ -59,6 +60,7 @@ include_directories(${CPPUNIT_INCLUDE_DIRS})
|
|||
list(APPEND test_digitalhf_sources
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test_digitalhf.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/qa_digitalhf.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/qa_doppler_correction_cc.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/qa_adaptive_dfe.cc
|
||||
)
|
||||
|
||||
|
@ -66,13 +68,11 @@ add_executable(test-digitalhf ${test_digitalhf_sources})
|
|||
|
||||
target_link_libraries(
|
||||
test-digitalhf
|
||||
${PYTHON_LIBRARIES}
|
||||
${GNURADIO_RUNTIME_LIBRARIES}
|
||||
${Boost_LIBRARIES}
|
||||
${CPPUNIT_LIBRARIES}
|
||||
gnuradio-digitalhf
|
||||
)
|
||||
MESSAGE("XXX ${PYTHON_LIBRARIES}")
|
||||
GR_ADD_TEST(test_digitalhf test-digitalhf)
|
||||
|
||||
########################################################################
|
||||
|
|
|
@ -39,51 +39,24 @@
|
|||
namespace gr {
|
||||
namespace digitalhf {
|
||||
|
||||
namespace {
|
||||
class GILLock {
|
||||
PyGILState_STATE _state;
|
||||
public:
|
||||
GILLock()
|
||||
:_state(PyGILState_Ensure()) {}
|
||||
~GILLock() {
|
||||
PyGILState_Release(_state);
|
||||
}
|
||||
} ;
|
||||
|
||||
boost::python::numpy::ndarray
|
||||
complex_vector_to_ndarray(std::vector<gr_complex> const& v) {
|
||||
return boost::python::numpy::from_data
|
||||
(&v.front(),
|
||||
boost::python::numpy::dtype::get_builtin<gr_complex>(),
|
||||
boost::python::make_tuple(v.size()),
|
||||
boost::python::make_tuple(sizeof(gr_complex)),
|
||||
boost::python::object());
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
adaptive_dfe::sptr
|
||||
adaptive_dfe::make(int sps, // samples per symbol
|
||||
int nB, // number of forward FIR taps
|
||||
int nF, // number of backward FIR taps
|
||||
int nW, // number of feedback taps
|
||||
float mu,
|
||||
float alpha,
|
||||
std::string python_module_name)
|
||||
float alpha)
|
||||
{
|
||||
return gnuradio::get_initial_sptr
|
||||
(new adaptive_dfe_impl(sps, nB, nF, nW, mu, alpha, python_module_name));
|
||||
(new adaptive_dfe_impl(sps, nB, nF, nW, mu, alpha));
|
||||
}
|
||||
|
||||
/*
|
||||
* The private constructor
|
||||
*/
|
||||
adaptive_dfe_impl::adaptive_dfe_impl(int sps, // samples per symbol
|
||||
int nB, // number of forward FIR taps
|
||||
int nF, // number of backward FIR taps
|
||||
int nW, // number of feedback taps
|
||||
float mu,
|
||||
float alpha,
|
||||
std::string python_module_name)
|
||||
float alpha)
|
||||
: gr::block("adaptive_dfe",
|
||||
gr::io_signature::make(1, 1, sizeof(gr_complex)),
|
||||
gr::io_signature::make(1, 1, sizeof(gr_complex)))
|
||||
|
@ -91,63 +64,61 @@ adaptive_dfe_impl::adaptive_dfe_impl(int sps, // samples per symbol
|
|||
, _nB(nB*sps)
|
||||
, _nF(nF*sps)
|
||||
, _nW(nW)
|
||||
, _nGuard(2*sps)
|
||||
, _mu(mu)
|
||||
, _alpha(alpha)
|
||||
, _use_symbol_taps(true)
|
||||
, _py_module_name(python_module_name)
|
||||
, _physicalLayer()
|
||||
// , _py_module_name(python_module_name)
|
||||
// , _physicalLayer()
|
||||
, _taps_samples(nullptr)
|
||||
, _taps_symbols(nullptr)
|
||||
, _hist_samples(nullptr)
|
||||
, _hist_symbols(nullptr)
|
||||
, _hist_sample_index(0)
|
||||
, _hist_symbol_index(0)
|
||||
, _ignore_filter_updates(0)
|
||||
, _saved_samples()
|
||||
, _sample_counter(0)
|
||||
, _constellations()
|
||||
, _npwr()
|
||||
, _npwr_counter()
|
||||
, _npwr_max_time_constant(10)
|
||||
, _constellation_index()
|
||||
, _samples()
|
||||
, _symbols()
|
||||
, _scramble()
|
||||
, _descrambled_symbols()
|
||||
, _symbol_counter(0)
|
||||
, _need_samples(false)
|
||||
, _save_soft_decisions(false)
|
||||
, _vec_soft_decisions()
|
||||
, _msg_port_name(pmt::mp("soft_dec"))
|
||||
, _msg_ports{{"soft_dec", pmt::mp("soft_dec")},
|
||||
{"frame_info", pmt::mp("frame_info")}}
|
||||
, _msg_metadata(pmt::make_dict())
|
||||
, _df(0)
|
||||
, _phase(0)
|
||||
, _b{0.338187046465954, -0.288839024460507}
|
||||
, _ud(0)
|
||||
, _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);
|
||||
|
||||
set_history(_nGuard+_nB+1);
|
||||
|
||||
message_port_register_out(_msg_ports["soft_dec"]);
|
||||
|
||||
pmt::pmt_t constellations_port = pmt::mp("constellations");
|
||||
message_port_register_in(constellations_port);
|
||||
set_msg_handler(constellations_port, boost::bind(&adaptive_dfe_impl::update_constellations, this, _1));
|
||||
|
||||
pmt::pmt_t frame_info_port = _msg_ports["frame_info"];
|
||||
message_port_register_in(frame_info_port);
|
||||
message_port_register_out(frame_info_port);
|
||||
set_msg_handler(frame_info_port, boost::bind(&adaptive_dfe_impl::update_frame_info, this, _1));
|
||||
}
|
||||
|
||||
/*
|
||||
* Our virtual destructor.
|
||||
*/
|
||||
adaptive_dfe_impl::~adaptive_dfe_impl()
|
||||
{
|
||||
_msg_port_name = pmt::PMT_NIL;
|
||||
_msg_metadata = pmt::PMT_NIL;
|
||||
_msg_metadata = pmt::PMT_NIL;
|
||||
VOLK_SAFE_DELETE(_taps_samples);
|
||||
VOLK_SAFE_DELETE(_taps_symbols);
|
||||
VOLK_SAFE_DELETE(_hist_samples);
|
||||
VOLK_SAFE_DELETE(_hist_symbols);
|
||||
}
|
||||
|
||||
void
|
||||
adaptive_dfe_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required)
|
||||
adaptive_dfe_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required)
|
||||
{
|
||||
ninput_items_required[0] = _sps*noutput_items;
|
||||
// [guard | nB | 1 | nF | guard ]
|
||||
ninput_items_required[0] = _sps*noutput_items + 2*_nGuard + _nB + _nF + 1;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -160,234 +131,102 @@ 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];
|
||||
|
||||
const int nin = ninput_items[0];
|
||||
|
||||
assert(ninput_items[0] >= 2*_nGuard + _nB + _nF + 1);
|
||||
if (ninput_items[0] < 2*_nGuard + _nB + _nF + 1)
|
||||
return 0;
|
||||
int const ninput = ninput_items[0] - _nGuard - _nF;
|
||||
|
||||
int nout = 0; // counter for produced output items
|
||||
int i = 0; // counter for consumed input items
|
||||
for (; i<ninput_items[0] && nout < noutput_items;) {
|
||||
assert(nout < noutput_items);
|
||||
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;
|
||||
switch (_state) {
|
||||
case WAIT_FOR_PREAMBLE: {
|
||||
std::vector<tag_t> v;
|
||||
get_tags_in_window(v, 0, history()-1, ninput, pmt::mp("preamble_start"));
|
||||
if (v.empty()) {
|
||||
consume(0, ninput - history()+1);
|
||||
} else {
|
||||
tag_t const& tag = v.front();
|
||||
// uint64_t const offset = tag.offset - nitems_read(0) + history() - 1;
|
||||
// std::cout << "========= offset= " << offset
|
||||
// << " tag.offset= " << tag.offset
|
||||
// << " nitems_read(0)= " << nitems_read(0)
|
||||
// << " tag.offset-nitems_read(0)= " << tag.offset - nitems_read(0) << " ==========" << std::endl;
|
||||
// for (int k=0; k<ninput; ++k)
|
||||
// std::cout << "SAMPLE: " << k << " " << k-int(offset) << " " << k+nitems_read(0) << " " << in[k] << std::endl;
|
||||
reset_filter();
|
||||
_descrambled_symbols.clear();
|
||||
publish_frame_info();
|
||||
consume(0, tag.offset - nitems_read(0));
|
||||
_state = WAIT_FOR_FRAME_INFO;
|
||||
GR_LOG_DEBUG(d_logger, "got preamble tag > wait for frame info");
|
||||
}
|
||||
break;
|
||||
} // WAIT_FOR_PREAMBLE
|
||||
case WAIT_FOR_FRAME_INFO: {
|
||||
//update_frame_info(delete_head_blocking(_msg_ports["frame_info"]));
|
||||
break;
|
||||
} // WAIT_FOR_MESSAGE
|
||||
case DO_FILTER: {
|
||||
// std::cout << "========= offset (DO_FILTER) nitems_read(0)= " << nitems_read(0) << " ==========" << std::endl;
|
||||
int ninput_processed = 0;
|
||||
for (int i=history()-1; i<ninput && nout<noutput_items; i+=_sps, ninput_processed+=_sps) {
|
||||
if (_symbol_counter == _symbols.size()) {
|
||||
publish_frame_info();
|
||||
publish_soft_dec();
|
||||
_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));
|
||||
_use_symbol_taps = true;
|
||||
_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();
|
||||
}
|
||||
}
|
||||
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<gr_complex> 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;
|
||||
}
|
||||
}
|
||||
} // INITIAL_DOPPLER_ESTIMATE_CONTINUE
|
||||
int const shift = recenter_filter_taps();
|
||||
if (shift != 0)
|
||||
ninput_processed += shift;
|
||||
|
||||
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;
|
||||
_samples.pop_back();
|
||||
if ((_sample_counter%_sps) == 0)
|
||||
out[nout++] = filter();
|
||||
_state = WAIT_FOR_FRAME_INFO;
|
||||
break;
|
||||
}
|
||||
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;
|
||||
}
|
||||
break;
|
||||
} // INITIAL_DOPPLER_ESTIMATE_CONTINUE
|
||||
|
||||
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()) {
|
||||
std::cout << "soft_dec " << _vec_soft_decisions.size() << "\n";
|
||||
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("packet_len"), pmt::mp(_vec_soft_decisions.size()));
|
||||
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();
|
||||
}
|
||||
} // 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]);
|
||||
}
|
||||
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);
|
||||
|
||||
// Tell runtime system how many output items we produced.
|
||||
// std::cout << "FILTER_CHECK: " << i << " " << i-1-_nB << " " << i+_nF << " " << in[i] << std::endl;
|
||||
assert(i+_nF < nin && i-1-_nB >= 0);
|
||||
out[nout++] = filter(in + i - _nB, in + i + _nF+1);
|
||||
} // next sample
|
||||
consume(0, ninput_processed);
|
||||
break;
|
||||
} // DO_FILTER
|
||||
}
|
||||
return nout;
|
||||
}
|
||||
|
||||
bool adaptive_dfe_impl::start()
|
||||
{
|
||||
gr::thread::scoped_lock lock(d_setlock);
|
||||
// make sure python is ready for threading
|
||||
if( Py_IsInitialized() ){
|
||||
GILLock gil_lock;
|
||||
if(PyEval_ThreadsInitialized() != 1 ){
|
||||
PyEval_InitThreads();
|
||||
}
|
||||
boost::python::numpy::initialize();
|
||||
} else {
|
||||
throw std::runtime_error("dont use adaptive_dfe without python!");
|
||||
}
|
||||
_taps_samples = (gr_complex*)(volk_malloc( (_nB+_nF+1)*sizeof(gr_complex), volk_get_alignment()));
|
||||
_taps_symbols = (gr_complex*)(volk_malloc( _nW*sizeof(gr_complex), volk_get_alignment()));
|
||||
_hist_samples = (gr_complex*)(volk_malloc(2*(_nB+_nF+1)*sizeof(gr_complex), volk_get_alignment()));
|
||||
_hist_symbols = (gr_complex*)(volk_malloc( 2*_nW*sizeof(gr_complex), volk_get_alignment()));
|
||||
|
||||
_samples.clear();
|
||||
std::fill_n(_hist_samples, 2*(_nB+_nF+1), 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_symbols, _nW, gr_complex(0));
|
||||
|
||||
_taps_samples[_nB+1] = 0.01;
|
||||
_taps_symbols[0] = 1;
|
||||
_taps_samples = (gr_complex*)(volk_malloc((_nB+_nF+1)*sizeof(gr_complex), volk_get_alignment()));
|
||||
_taps_symbols = (gr_complex*)(volk_malloc( _nW*sizeof(gr_complex), volk_get_alignment()));
|
||||
_hist_symbols = (gr_complex*)(volk_malloc( 2*_nW*sizeof(gr_complex), volk_get_alignment()));
|
||||
|
||||
reset_filter();
|
||||
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;
|
||||
try {
|
||||
boost::python::object module = boost::python::import(boost::python::str("digitalhf.physical_layer." + _py_module_name));
|
||||
boost::python::object PhysicalLayer = module.attr("PhysicalLayer");
|
||||
_physicalLayer = PhysicalLayer(_sps);
|
||||
update_constellations(_physicalLayer.attr("get_constellations")());
|
||||
} catch (boost::python::error_already_set const&) {
|
||||
PyErr_Print();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool adaptive_dfe_impl::stop()
|
||||
{
|
||||
gr::thread::scoped_lock lock(d_setlock);
|
||||
GR_LOG_DEBUG(d_logger, "adaptive_dfe_impl::stop()");
|
||||
GILLock gil_lock;
|
||||
_physicalLayer = boost::python::object();
|
||||
VOLK_SAFE_DELETE(_taps_samples);
|
||||
VOLK_SAFE_DELETE(_taps_symbols);
|
||||
VOLK_SAFE_DELETE(_hist_samples);
|
||||
VOLK_SAFE_DELETE(_hist_symbols);
|
||||
return true;
|
||||
}
|
||||
|
||||
gr_complex adaptive_dfe_impl::filter() {
|
||||
gr_complex adaptive_dfe_impl::filter(gr_complex const* start, gr_complex const* end) {
|
||||
assert(end-start == _nB + _nF + 1);
|
||||
|
||||
gr_complex filter_output = 0;
|
||||
volk_32fc_x2_dot_prod_32fc(&filter_output,
|
||||
_hist_samples+_hist_sample_index,
|
||||
start,
|
||||
_taps_samples,
|
||||
_nB+_nF+1);
|
||||
gr_complex dot_symbols=0;
|
||||
gr::digital::constellation_sptr constell = _constellations[_constellation_index];
|
||||
bool const update_taps = constell->bits_per_symbol() <= 3;
|
||||
bool const update_taps = true;//constell->bits_per_symbol() <= 3;
|
||||
if (constell->bits_per_symbol() > 3)
|
||||
_use_symbol_taps = false;
|
||||
if (_use_symbol_taps) {
|
||||
|
@ -397,30 +236,28 @@ gr_complex adaptive_dfe_impl::filter() {
|
|||
}
|
||||
filter_output += dot_symbols;
|
||||
}
|
||||
assert(_symbol_counter < _symbols.size());
|
||||
gr_complex known_symbol = _symbols[_symbol_counter];
|
||||
bool const is_known = std::abs(known_symbol) > 1e-5;
|
||||
if (not is_known) { // not known
|
||||
if (not is_known) {
|
||||
gr_complex const descrambled_filter_output = std::conj(_scramble[_symbol_counter]) * filter_output;
|
||||
unsigned int jc = constell->decision_maker(&descrambled_filter_output);
|
||||
unsigned int const jc = constell->decision_maker(&descrambled_filter_output);
|
||||
gr_complex descrambled_symbol = 0;
|
||||
constell->map_to_points(jc, &descrambled_symbol);
|
||||
|
||||
if (_save_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<float> const 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].filter(err));
|
||||
std::copy(soft_dec.begin(), soft_dec.end(), std::back_inserter<std::vector<float> >(_vec_soft_decisions));
|
||||
}
|
||||
known_symbol = _scramble[_symbol_counter] * descrambled_symbol;
|
||||
}
|
||||
// std::cout << "FILTER: " << filter_output <<" " << known_symbol << " " << start[_nB+1] << std::endl;
|
||||
if (is_known || update_taps) {
|
||||
gr_complex const err = filter_output - known_symbol;
|
||||
for (int j=0; j<_nB+_nF+1; ++j) {
|
||||
assert(_hist_sample_index+j < 2*(_nB+_nF+1));
|
||||
_taps_samples[j] -= _mu*err*std::conj(_hist_samples[_hist_sample_index+j]);
|
||||
}
|
||||
for (int j=0; j<_nB+_nF+1; ++j)
|
||||
_taps_samples[j] -= _mu*err*std::conj(start[j]);
|
||||
|
||||
if (_use_symbol_taps) {
|
||||
for (int j=0; j<_nW; ++j) {
|
||||
assert(_hist_symbol_index+j < 2*_nW);
|
||||
|
@ -435,165 +272,98 @@ gr_complex adaptive_dfe_impl::filter() {
|
|||
return filter_output*std::conj(_scramble[_symbol_counter++]);
|
||||
}
|
||||
|
||||
void adaptive_dfe_impl::recenter_filter_taps() {
|
||||
int
|
||||
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) {
|
||||
// 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) {
|
||||
// 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) {
|
||||
return +2*_sps;
|
||||
}
|
||||
if (idx_max-_nB-1 < -2*_sps) {
|
||||
// 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) {
|
||||
gr::thread::scoped_lock lock(d_setlock);
|
||||
GR_LOG_DEBUG(d_logger, "adaptive_dfe_impl::set_mode "+ mode);
|
||||
GILLock gil_lock;
|
||||
try {
|
||||
_physicalLayer.attr("set_mode")(mode);
|
||||
} catch (boost::python::error_already_set const&) {
|
||||
PyErr_Print();
|
||||
return;
|
||||
return -2*_sps;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void adaptive_dfe_impl::update_constellations(boost::python::object obj)
|
||||
void adaptive_dfe_impl::reset_filter()
|
||||
{
|
||||
int const n = boost::python::extract<int>(obj.attr("__len__")());
|
||||
std::fill_n(_taps_samples, _nB+_nF+1, gr_complex(0));
|
||||
std::fill_n(_taps_symbols, _nW, gr_complex(0));
|
||||
std::fill_n(_hist_symbols, 2*_nW, gr_complex(0));
|
||||
_taps_samples[_nB+1] = 0.01;
|
||||
_taps_symbols[0] = 1;
|
||||
_hist_symbol_index = 0;
|
||||
}
|
||||
|
||||
void adaptive_dfe_impl::publish_frame_info()
|
||||
{
|
||||
pmt::pmt_t data = pmt::make_dict();
|
||||
GR_LOG_DEBUG(d_logger, str(boost::format("publish_frame_info %d == %d") % _descrambled_symbols.size() % _symbols.size()));
|
||||
data = pmt::dict_add(data, pmt::mp("symbols"), pmt::init_c32vector(_descrambled_symbols.size(), &_descrambled_symbols.front()));
|
||||
message_port_pub(_msg_ports["frame_info"], data);
|
||||
_descrambled_symbols.clear();
|
||||
}
|
||||
|
||||
void adaptive_dfe_impl::publish_soft_dec()
|
||||
{
|
||||
if (_vec_soft_decisions.empty())
|
||||
return;
|
||||
message_port_pub(_msg_ports["soft_dec"],
|
||||
pmt::cons(pmt::dict_add(_msg_metadata, pmt::mp("packet_len"), pmt::mp(_vec_soft_decisions.size())),
|
||||
pmt::init_f32vector(_vec_soft_decisions.size(), _vec_soft_decisions)));
|
||||
_vec_soft_decisions.clear();
|
||||
}
|
||||
|
||||
void adaptive_dfe_impl::update_constellations(pmt::pmt_t data) {
|
||||
int const n = pmt::length(data);
|
||||
_constellations.resize(n);
|
||||
_npwr.resize(n);
|
||||
_npwr_counter.resize(n);
|
||||
std::cout << "adaptive_dfe_impl::update_constellations " << data << std::endl;
|
||||
std::cout << "adaptive_dfe_impl::update_constellations n=" << n << std::endl;
|
||||
unsigned int const rotational_symmetry = 0;
|
||||
unsigned int const dimensionality = 1;
|
||||
|
||||
for (int i=0; i<n; ++i) {
|
||||
boost::python::numpy::ndarray const& array = boost::python::numpy::array(obj[i]);
|
||||
char const* data = array.get_data();
|
||||
int const m = array.shape(0);
|
||||
std::vector<gr_complex> constell(m);
|
||||
std::vector<int> pre_diff_code(m);
|
||||
for (int j=0; j<m; ++j) {
|
||||
std::memcpy(&constell[j], data+9*j, sizeof(gr_complex));
|
||||
pre_diff_code[j] = (data+9*j)[8];
|
||||
}
|
||||
unsigned int const rotational_symmetry = 0;
|
||||
unsigned int const dimensionality = 1;
|
||||
_constellations[i] = gr::digital::constellation_calcdist::make(constell, pre_diff_code, rotational_symmetry, dimensionality);
|
||||
_npwr[i] = 0.0f;
|
||||
_npwr_counter[i] = 0;
|
||||
pmt::pmt_t c = pmt::vector_ref(data, i);
|
||||
int const idx = pmt::to_long(pmt::dict_ref(c, pmt::mp("idx"), pmt::from_long(-1)));
|
||||
assert(idx>=0 && idx < n);
|
||||
_constellations[idx] = gr::digital::constellation_calcdist::make
|
||||
(pmt::c32vector_elements(pmt::dict_ref(c, pmt::mp("points"), pmt::PMT_NIL)),
|
||||
pmt::s32vector_elements(pmt::dict_ref(c, pmt::mp("symbols"), pmt::PMT_NIL)),
|
||||
rotational_symmetry, dimensionality);
|
||||
_npwr[i].reset(_npwr_max_time_constant);
|
||||
}
|
||||
}
|
||||
bool adaptive_dfe_impl::update_frame_information(boost::python::object obj)
|
||||
{
|
||||
int const n = boost::python::extract<int>(obj.attr("__len__")());
|
||||
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);
|
||||
_symbols.resize(m);
|
||||
_scramble.resize(m);
|
||||
_descrambled_symbols.resize(m);
|
||||
_samples.clear();
|
||||
for (int i=0; i<m; ++i) {
|
||||
std::memcpy(&_symbols[i], data+16*i, sizeof(gr_complex));
|
||||
std::memcpy(&_scramble[i], data+16*i+8, sizeof(gr_complex));
|
||||
// std::cout << "get_frame " << i << " " << _symbols[i] << " " << _scramble[i] << std::endl;
|
||||
}
|
||||
_constellation_index = boost::python::extract<int> (obj[1]);
|
||||
_need_samples = boost::python::extract<bool>(obj[2]);
|
||||
_save_soft_decisions = boost::python::extract<bool>(obj[3]);
|
||||
return true;
|
||||
}
|
||||
bool adaptive_dfe_impl::update_doppler_information(boost::python::object obj)
|
||||
{
|
||||
int const n = boost::python::extract<int>(obj.attr("__len__")());
|
||||
assert(n==2);
|
||||
bool const do_continue = boost::python::extract<bool>(obj[0]);
|
||||
if (!do_continue) {
|
||||
_phase = 0;
|
||||
_df = 0;
|
||||
std::fill_n(_hist_samples, 2*(_nB+_nF+1), gr_complex(0));
|
||||
_hist_sample_index = 0;
|
||||
_sample_counter = 0;
|
||||
return false;
|
||||
}
|
||||
float const doppler = boost::python::extract<float>(obj[1]);
|
||||
update_pll(doppler);
|
||||
return true;
|
||||
}
|
||||
|
||||
void adaptive_dfe_impl::update_pll(float doppler) {
|
||||
if (doppler == 0)
|
||||
return;
|
||||
float const delta_f = doppler/_sps;
|
||||
if (_df == 0) { // init
|
||||
_ud = _df = delta_f;
|
||||
} else {
|
||||
float const ud_old = _ud;
|
||||
_ud = delta_f;
|
||||
_df +=_b[0]*_ud + _b[1]*ud_old;
|
||||
}
|
||||
GR_LOG_DEBUG(d_logger, str(boost::format("PLL: df=%f delta_f=%f (rad/sample)") % _df % delta_f));
|
||||
}
|
||||
void adaptive_dfe_impl::insert_sample(gr_complex z) {
|
||||
// insert sample into the circular buffer
|
||||
_hist_samples[_hist_sample_index] = _hist_samples[_hist_sample_index+_nB+_nF+1] = z * gr_expj(-_phase);
|
||||
if (++_hist_sample_index == _nB+_nF+1)
|
||||
_hist_sample_index = 0;
|
||||
if (z != gr_complex(0))
|
||||
update_local_oscillator();
|
||||
}
|
||||
void adaptive_dfe_impl:: update_local_oscillator() {
|
||||
_phase += _df;
|
||||
if (_phase > M_PI)
|
||||
_phase -= 2*M_PI;
|
||||
if (_phase < -M_PI)
|
||||
_phase += 2*M_PI;
|
||||
}
|
||||
bool adaptive_dfe_impl::get_correlation_tag(uint64_t i, uint64_t& offset, float& phase_est) {
|
||||
std::vector<tag_t> v;
|
||||
get_tags_in_window(v, 0, i,i+1);
|
||||
for (int j=0; j<v.size(); ++j) {
|
||||
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")) {
|
||||
phase_est = pmt::to_double(v[j].value);
|
||||
std::cout << "phase_est " << v[j].offset <<" " << nitems_read(0) << " " << phase_est << std::endl;
|
||||
offset = v[j].offset - nitems_read(0);
|
||||
}
|
||||
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 > 10e3)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
void adaptive_dfe_impl::update_frame_info(pmt::pmt_t data)
|
||||
{
|
||||
//GR_LOG_DEBUG(d_logger,str(boost::format("adaptive_dfe_impl::update_frame_info() %s") % data));
|
||||
_symbols = pmt::c32vector_elements(pmt::dict_ref(data, pmt::mp("symb"), pmt::PMT_NIL));
|
||||
_scramble = pmt::c32vector_elements(pmt::dict_ref(data, pmt::mp("scramble"), pmt::PMT_NIL));
|
||||
_constellation_index = pmt::to_long(pmt::dict_ref(data, pmt::mp("constellation_idx"), pmt::PMT_NIL));
|
||||
_save_soft_decisions = pmt::to_bool(pmt::dict_ref(data, pmt::mp("save_soft_dec"), pmt::PMT_F));
|
||||
bool const do_continue = pmt::to_bool(pmt::dict_ref(data, pmt::mp("do_continue"), pmt::PMT_F));
|
||||
assert(_symbols.size() == _scramble.size());
|
||||
_descrambled_symbols.resize(_symbols.size());
|
||||
_vec_soft_decisions.clear();
|
||||
_symbol_counter = 0;
|
||||
_state = (do_continue ? DO_FILTER : WAIT_FOR_PREAMBLE);
|
||||
}
|
||||
|
||||
} /* namespace digitalhf */
|
||||
|
|
|
@ -21,18 +21,42 @@
|
|||
#ifndef INCLUDED_DIGITALHF_ADAPTIVE_DFE_IMPL_H
|
||||
#define INCLUDED_DIGITALHF_ADAPTIVE_DFE_IMPL_H
|
||||
|
||||
#include <boost/python.hpp>
|
||||
#include <boost/python/numpy.hpp>
|
||||
#include <gnuradio/digital/constellation.h>
|
||||
#include <digitalhf/adaptive_dfe.h>
|
||||
|
||||
namespace gr {
|
||||
namespace digitalhf {
|
||||
|
||||
class constellation_distance_filter {
|
||||
public:
|
||||
constellation_distance_filter(int max_time_constant=10)
|
||||
: _max_time_constant(max_time_constant)
|
||||
, _counter(0)
|
||||
, _pwr(0) {}
|
||||
|
||||
void reset(int max_time_constant) {
|
||||
_max_time_constant = max_time_constant;
|
||||
_counter = 0;
|
||||
_pwr = 0;
|
||||
}
|
||||
float filter(float x) {
|
||||
_counter += (_counter < _max_time_constant);
|
||||
float const alpha = 1.0f/_counter;
|
||||
_pwr = (1-alpha)*_pwr + alpha*x;
|
||||
return _pwr;
|
||||
}
|
||||
protected:
|
||||
private:
|
||||
int _max_time_constant;
|
||||
int _counter;
|
||||
float _pwr; // filtered distance to constellation point
|
||||
} ;
|
||||
|
||||
class adaptive_dfe_impl : public adaptive_dfe {
|
||||
private:
|
||||
int _sps;
|
||||
int _nB, _nF, _nW;
|
||||
int _nGuard;
|
||||
|
||||
float _mu;
|
||||
float _alpha;
|
||||
|
@ -40,64 +64,45 @@ private:
|
|||
bool _use_symbol_taps;
|
||||
|
||||
// module name w.r.t. digitalhf.physical_layer containing a PhysicalLayer class
|
||||
std::string _py_module_name;
|
||||
boost::python::object _physicalLayer; // class instance of physical layer description
|
||||
// std::string _py_module_name;
|
||||
// boost::python::object _physicalLayer; // class instance of physical layer description
|
||||
|
||||
gr_complex* _taps_samples;
|
||||
gr_complex* _taps_symbols;
|
||||
|
||||
gr_complex* _hist_samples;
|
||||
gr_complex* _hist_symbols;
|
||||
|
||||
int _hist_sample_index;
|
||||
int _hist_symbol_index;
|
||||
|
||||
int _ignore_filter_updates;
|
||||
std::vector<gr_complex> _saved_samples;
|
||||
|
||||
uint64_t _sample_counter;
|
||||
|
||||
std::vector<gr::digital::constellation_sptr> _constellations;
|
||||
std::vector<float> _npwr;
|
||||
std::vector<int> _npwr_counter;
|
||||
std::vector<constellation_distance_filter> _npwr;
|
||||
int _npwr_max_time_constant;
|
||||
int _constellation_index;
|
||||
std::vector<gr_complex> _samples;
|
||||
std::vector<gr_complex> _symbols;
|
||||
std::vector<gr_complex> _scramble;
|
||||
std::vector<gr_complex> _descrambled_symbols;
|
||||
int _symbol_counter;
|
||||
|
||||
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
|
||||
float _df; // frequency offset in radians per sample
|
||||
float _phase; // accumulated phase for frequency correction
|
||||
const float _b[2];
|
||||
float _ud;
|
||||
std::map<std::string, pmt::pmt_t> _msg_ports;
|
||||
pmt::pmt_t _msg_metadata;
|
||||
|
||||
enum state {
|
||||
WAIT_FOR_PREAMBLE,
|
||||
INITIAL_DOPPLER_ESTIMATE,
|
||||
INITIAL_DOPPLER_ESTIMATE_CONTINUE,
|
||||
WAIT_FOR_FRAME_INFO,
|
||||
DO_FILTER
|
||||
} _state;
|
||||
|
||||
void update_constellations(boost::python::object obj);
|
||||
bool update_frame_information(boost::python::object obj);
|
||||
bool update_doppler_information(boost::python::object obj);
|
||||
// void update_constellations(boost::python::object obj);
|
||||
void update_constellations(pmt::pmt_t );
|
||||
void update_frame_info(pmt::pmt_t );
|
||||
|
||||
void update_local_oscillator();
|
||||
gr_complex filter();
|
||||
void recenter_filter_taps();
|
||||
gr_complex filter(gr_complex const* start, gr_complex const* end);
|
||||
int recenter_filter_taps();
|
||||
void reset_filter();
|
||||
|
||||
void insert_sample(gr_complex z);
|
||||
void update_pll(float doppler);
|
||||
bool get_correlation_tag(uint64_t i, uint64_t& offset, float& phase_est);
|
||||
void publish_frame_info();
|
||||
void publish_soft_dec();
|
||||
|
||||
public:
|
||||
adaptive_dfe_impl(int sps, // samples per symbol
|
||||
|
@ -105,8 +110,7 @@ public:
|
|||
int nF, // number of backward FIR taps
|
||||
int nW, // number of symbol taps
|
||||
float mu,
|
||||
float alpha,
|
||||
std::string physical_layer_description);
|
||||
float alpha);
|
||||
virtual ~adaptive_dfe_impl();
|
||||
|
||||
void forecast (int noutput_items, gr_vector_int &ninput_items_required);
|
||||
|
@ -120,8 +124,7 @@ public:
|
|||
gr_vector_void_star &output_items);
|
||||
|
||||
virtual void set_mu(float mu) { _mu = mu; }
|
||||
virtual void set_mode(std::string);
|
||||
|
||||
virtual void set_alpha(float alpha) { _alpha = alpha; }
|
||||
} ;
|
||||
|
||||
} // namespace digitalhf
|
||||
|
|
153
lib/doppler_correction_cc_impl.cc
Normal file
153
lib/doppler_correction_cc_impl.cc
Normal file
|
@ -0,0 +1,153 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2018 hcab14@gmail.com.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <gnuradio/expj.h>
|
||||
#include <gnuradio/logger.h>
|
||||
|
||||
#include "doppler_correction_cc_impl.h"
|
||||
|
||||
namespace gr {
|
||||
namespace digitalhf {
|
||||
|
||||
doppler_correction_cc::sptr
|
||||
doppler_correction_cc::make(unsigned int preamble_length, unsigned int preamble_length_cc)
|
||||
{
|
||||
return gnuradio::get_initial_sptr
|
||||
(new doppler_correction_cc_impl(preamble_length, preamble_length_cc));
|
||||
}
|
||||
|
||||
/*
|
||||
* The private constructor
|
||||
*/
|
||||
doppler_correction_cc_impl::doppler_correction_cc_impl(unsigned int preamble_length,
|
||||
unsigned int preamble_length_cc)
|
||||
: gr::sync_block("doppler_correction_cc",
|
||||
gr::io_signature::make(1, 1, sizeof(gr_complex)),
|
||||
gr::io_signature::make(1, 1, sizeof(gr_complex)))
|
||||
, _preamble_length(preamble_length)
|
||||
, _preamble_length_cc(preamble_length_cc)
|
||||
, _rotator()
|
||||
, _state(WAIT_FOR_PHASE_EST_TAG)
|
||||
, _msg_metadata(pmt::make_dict())
|
||||
, _port_name(pmt::mp("doppler"))
|
||||
, _phase_est(0)
|
||||
{
|
||||
GR_LOG_DECLARE_LOGPTR(d_logger);
|
||||
GR_LOG_ASSIGN_LOGPTR(d_logger, "doppler_correction_cc");
|
||||
message_port_register_out(_port_name);
|
||||
message_port_register_in (_port_name);
|
||||
// set_msg_handler(_port_name, boost::bind(&doppler_correction_cc_impl::handle_message, this, _1));
|
||||
set_tag_propagation_policy(TPP_DONT);
|
||||
set_output_multiple(2*_preamble_length); // without this the CPU usage goes up to 100%
|
||||
}
|
||||
|
||||
doppler_correction_cc_impl::~doppler_correction_cc_impl()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
doppler_correction_cc_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required)
|
||||
{
|
||||
ninput_items_required[0] = noutput_items + _preamble_length;
|
||||
}
|
||||
|
||||
void
|
||||
doppler_correction_cc_impl::handle_message(pmt::pmt_t msg)
|
||||
{
|
||||
bool const success = pmt::to_bool(pmt::dict_ref(msg, pmt::mp("success"), pmt::get_PMT_F()));
|
||||
if (!success) {
|
||||
// GR_LOG_DEBUG(d_logger, "next state > CONSUME_AND_SKIP success=false");
|
||||
_state = CONSUME_AND_SKIP;
|
||||
return;
|
||||
}
|
||||
float const doppler = pmt::to_float(pmt::dict_ref(msg, pmt::mp("doppler"), pmt::from_float(0)));
|
||||
_rotator.set_phase(gr_expj(-_phase_est + 0.5*doppler*_preamble_length_cc));
|
||||
_rotator.set_phase_incr(gr_expj(-doppler));
|
||||
// GR_LOG_DEBUG(d_logger, str(boost::format("next state > CONSUME_AND_INSERT_PREAMBLE_TAG phase_est=%f doppler=%f")
|
||||
// % (_phase_est - 0.5*doppler*_preamble_length_cc)
|
||||
// % doppler));
|
||||
_state = CONSUME_AND_INSERT_PREAMBLE_TAG;
|
||||
}
|
||||
|
||||
int
|
||||
doppler_correction_cc_impl::work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
gr_complex const* in = (gr_complex const*)input_items[0];
|
||||
gr_complex *out = (gr_complex *) output_items[0];
|
||||
|
||||
// assert(noutput_items >= _preamble_length);
|
||||
noutput_items -= _preamble_length;
|
||||
if (noutput_items < 0)
|
||||
return 0;
|
||||
int nout = 0;
|
||||
switch (_state) {
|
||||
case WAIT_FOR_PHASE_EST_TAG: {
|
||||
std::vector<tag_t> v;
|
||||
get_tags_in_window(v, 0, 0, noutput_items, pmt::mp("phase_est"));
|
||||
if (v.empty()) {
|
||||
nout = noutput_items;
|
||||
} else {
|
||||
tag_t const& tag = v.front();
|
||||
uint64_t const offset = tag.offset - nitems_read(0);
|
||||
nout = offset;
|
||||
_phase_est = pmt::to_double(tag.value);
|
||||
_msg_metadata = pmt::dict_add(_msg_metadata, pmt::mp("packet_len"), pmt::from_long(_preamble_length));
|
||||
message_port_pub(_port_name,
|
||||
pmt::cons(_msg_metadata,
|
||||
pmt::init_c32vector(_preamble_length, in+nout)));
|
||||
// GR_LOG_DEBUG(d_logger, str(boost::format("next state > WAIT_FOR_MSG %lld phase_est=%f") % tag.offset % _phase_est));
|
||||
_state = WAIT_FOR_MSG;
|
||||
}
|
||||
break;
|
||||
} // WAIT_FOR_PHASE_EST_TAG
|
||||
case WAIT_FOR_MSG: {
|
||||
// GR_LOG_DEBUG(d_logger, "WAIT_FOR_MSG");
|
||||
handle_message(delete_head_blocking(_port_name));
|
||||
break;
|
||||
} // WAIT_FOR_MSG
|
||||
case CONSUME_AND_INSERT_PREAMBLE_TAG: {
|
||||
add_item_tag(0, nitems_read(0), pmt::mp("preamble_start"), pmt::from_long(0));
|
||||
nout = _preamble_length;
|
||||
// GR_LOG_DEBUG(d_logger, str(boost::format("next state > WAIT_FOR_PHASE_EST_TAG %lld") % nitems_read(0)));
|
||||
_state = WAIT_FOR_PHASE_EST_TAG;
|
||||
break;
|
||||
} // CONSUME_AND_INSERT_PREAMBLE_TAG
|
||||
case CONSUME_AND_SKIP: {
|
||||
nout = _preamble_length;
|
||||
// GR_LOG_DEBUG(d_logger, str(boost::format("next state > WAIT_FOR_PHASE_EST_TAG %lld") % nitems_read(0)));
|
||||
_state = WAIT_FOR_PHASE_EST_TAG;
|
||||
break;
|
||||
} // CONSUME_AND_SKIP
|
||||
}
|
||||
// apply current doppler correction to all produced samples
|
||||
_rotator.rotateN(out, in, nout);
|
||||
// Tell runtime system how many output items we produced.
|
||||
return nout;
|
||||
}
|
||||
|
||||
} /* namespace digitalhf */
|
||||
} /* namespace gr */
|
65
lib/doppler_correction_cc_impl.h
Normal file
65
lib/doppler_correction_cc_impl.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2018 hcab14@gmail.com.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_DIGITALHF_DOPPLER_CORRECTION_CC_IMPL_H
|
||||
#define INCLUDED_DIGITALHF_DOPPLER_CORRECTION_CC_IMPL_H
|
||||
|
||||
#include <gnuradio/blocks/rotator.h>
|
||||
|
||||
#include <digitalhf/doppler_correction_cc.h>
|
||||
|
||||
namespace gr {
|
||||
namespace digitalhf {
|
||||
|
||||
class doppler_correction_cc_impl : public doppler_correction_cc
|
||||
{
|
||||
private:
|
||||
unsigned int _preamble_length; // length of preamble (in samples)
|
||||
unsigned int _preamble_length_cc; // length of the part of the preamble used for cross correlation (in samples)
|
||||
blocks::rotator _rotator;
|
||||
enum {
|
||||
WAIT_FOR_PHASE_EST_TAG, // wait for a tag from corr_est_cc
|
||||
WAIT_FOR_MSG, // wait for response from msg_proxy
|
||||
CONSUME_AND_INSERT_PREAMBLE_TAG, // insert a preamble tag (=doppler calculation was successful)
|
||||
CONSUME_AND_SKIP // do not intsert a tag and skip the samples (=doppler calculation was not successful)
|
||||
} _state;
|
||||
pmt::pmt_t _msg_metadata;
|
||||
pmt::pmt_t _port_name;
|
||||
|
||||
float _phase_est;
|
||||
|
||||
public:
|
||||
doppler_correction_cc_impl(unsigned int preamble_length, unsigned int preamble_length_cc);
|
||||
virtual ~doppler_correction_cc_impl();
|
||||
|
||||
void forecast(int noutput_items, gr_vector_int &ninput_items_required);
|
||||
|
||||
int work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items);
|
||||
protected:
|
||||
void handle_message(pmt::pmt_t msg);
|
||||
|
||||
};
|
||||
|
||||
} // namespace digitalhf
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_DIGITALHF_DOPPLER_CORRECTION_CC_IMPL_H */
|
|
@ -28,12 +28,14 @@
|
|||
|
||||
#include "qa_digitalhf.h"
|
||||
#include "qa_adaptive_dfe.h"
|
||||
#include "qa_doppler_correction_cc.h"
|
||||
|
||||
CppUnit::TestSuite *
|
||||
qa_digitalhf::suite()
|
||||
{
|
||||
CppUnit::TestSuite *s = new CppUnit::TestSuite("digitalhf");
|
||||
s->addTest(gr::digitalhf::qa_adaptive_dfe::suite());
|
||||
s->addTest(gr::digitalhf::qa_doppler_correction_cc::suite());
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
37
lib/qa_doppler_correction_cc.cc
Normal file
37
lib/qa_doppler_correction_cc.cc
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2018 hcab14@gmail.com.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include <gnuradio/attributes.h>
|
||||
#include <cppunit/TestAssert.h>
|
||||
#include "qa_doppler_correction_cc.h"
|
||||
#include <digitalhf/doppler_correction_cc.h>
|
||||
|
||||
namespace gr {
|
||||
namespace digitalhf {
|
||||
|
||||
void
|
||||
qa_doppler_correction_cc::t1()
|
||||
{
|
||||
// Put test here
|
||||
}
|
||||
|
||||
} /* namespace digitalhf */
|
||||
} /* namespace gr */
|
46
lib/qa_doppler_correction_cc.h
Normal file
46
lib/qa_doppler_correction_cc.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2018 hcab14@gmail.com.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _QA_DOPPLER_CORRECTION_CC_H_
|
||||
#define _QA_DOPPLER_CORRECTION_CC_H_
|
||||
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
#include <cppunit/TestCase.h>
|
||||
|
||||
namespace gr {
|
||||
namespace digitalhf {
|
||||
|
||||
class qa_doppler_correction_cc : public CppUnit::TestCase
|
||||
{
|
||||
public:
|
||||
CPPUNIT_TEST_SUITE(qa_doppler_correction_cc);
|
||||
CPPUNIT_TEST(t1);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
private:
|
||||
void t1();
|
||||
};
|
||||
|
||||
} /* namespace digitalhf */
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* _QA_DOPPLER_CORRECTION_CC_H_ */
|
||||
|
|
@ -32,7 +32,8 @@ endif()
|
|||
GR_PYTHON_INSTALL(
|
||||
FILES
|
||||
__init__.py
|
||||
DESTINATION ${GR_PYTHON_DIR}/digitalhf
|
||||
physical_layer_driver.py
|
||||
msg_proxy.py DESTINATION ${GR_PYTHON_DIR}/digitalhf
|
||||
)
|
||||
|
||||
########################################################################
|
||||
|
@ -45,3 +46,6 @@ set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/swig)
|
|||
GR_ADD_TEST(qa_adaptive_dfe ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_adaptive_dfe.py)
|
||||
|
||||
add_subdirectory(physical_layer)
|
||||
GR_ADD_TEST(qa_physical_layer_driver_driver ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_physical_layer_driver_driver.py)
|
||||
GR_ADD_TEST(qa_doppler_correction_cc ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_doppler_correction_cc.py)
|
||||
GR_ADD_TEST(qa_msg_proxy ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_msg_proxy.py)
|
||||
|
|
|
@ -31,4 +31,6 @@ except ImportError:
|
|||
pass
|
||||
|
||||
# import any pure python here
|
||||
from physical_layer_driver import physical_layer_driver
|
||||
from msg_proxy import msg_proxy
|
||||
#
|
||||
|
|
70
python/msg_proxy.py
Normal file
70
python/msg_proxy.py
Normal file
|
@ -0,0 +1,70 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2018 hcab14@gmail.com.
|
||||
#
|
||||
# This is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This software is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this software; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
|
||||
import numpy as np
|
||||
from gnuradio import gr
|
||||
import pmt
|
||||
|
||||
class msg_proxy(gr.basic_block):
|
||||
"""
|
||||
docstring for block msg_proxy
|
||||
"""
|
||||
def __init__(self, physical_layer_object):
|
||||
gr.basic_block.__init__(self,
|
||||
name="msg_proxy",
|
||||
in_sig=[],
|
||||
out_sig=[])
|
||||
self._obj = physical_layer_object
|
||||
|
||||
self._port_doppler = pmt.intern("doppler")
|
||||
self.message_port_register_in(self._port_doppler)
|
||||
self.message_port_register_out(self._port_doppler)
|
||||
self.set_msg_handler(self._port_doppler, self.msg_handler_doppler)
|
||||
|
||||
self._port_frame_info = pmt.intern("frame_info")
|
||||
self.message_port_register_in(self._port_frame_info)
|
||||
self.message_port_register_out(self._port_frame_info)
|
||||
self.set_msg_handler(self._port_frame_info, self.msg_handler_frame)
|
||||
|
||||
def msg_handler_doppler(self, msg_in):
|
||||
## print('-------------------- msg_handler_doppler --------------------')
|
||||
iq_samples = pmt.to_python(pmt.cdr(msg_in))
|
||||
success,doppler = self._obj.get_doppler(iq_samples)
|
||||
msg_out = pmt.make_dict()
|
||||
msg_out = pmt.dict_add(msg_out, pmt.intern('success'), pmt.to_pmt(success))
|
||||
msg_out = pmt.dict_add(msg_out, pmt.intern('doppler'), pmt.to_pmt(doppler))
|
||||
## print(msg_out)
|
||||
self.message_port_pub(self._port_doppler, msg_out)
|
||||
|
||||
def msg_handler_frame(self, msg_in):
|
||||
## print('-------------------- msg_handler_frame --------------------')
|
||||
## print(msg_in)
|
||||
symbols = pmt.to_python(pmt.dict_ref(msg_in, pmt.intern('symbols'), pmt.PMT_NIL))
|
||||
symb,constellation_idx,do_continue,save_soft_dec = self._obj.get_next_frame(symbols)
|
||||
##print('symb=', symb, symb['symb'], symb['scramble'])
|
||||
msg_out = pmt.make_dict()
|
||||
msg_out = pmt.dict_add(msg_out, pmt.intern('symb'), pmt.to_pmt(symb['symb']))
|
||||
msg_out = pmt.dict_add(msg_out, pmt.intern('scramble'), pmt.to_pmt(symb['scramble']))
|
||||
msg_out = pmt.dict_add(msg_out, pmt.intern('constellation_idx'), pmt.to_pmt(constellation_idx))
|
||||
msg_out = pmt.dict_add(msg_out, pmt.intern('do_continue'), pmt.to_pmt(do_continue))
|
||||
msg_out = pmt.dict_add(msg_out, pmt.intern('save_soft_dec'), pmt.to_pmt(save_soft_dec))
|
||||
## print(msg_out)
|
||||
self.message_port_pub(self._port_frame_info, msg_out)
|
|
@ -114,20 +114,35 @@ class PhysicalLayer(object):
|
|||
def get_constellations(self):
|
||||
return self._constellations
|
||||
|
||||
def get_frame(self):
|
||||
def get_next_frame(self, symbols):
|
||||
"""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 if the processing should continue
|
||||
[3] ... a boolean indicating if the soft decision for the unknown
|
||||
symbols are saved"""
|
||||
print('-------------------- get_frame --------------------',
|
||||
self._pre_counter, self._frame_counter)
|
||||
## --- preamble frame ----
|
||||
if self._pre_counter != 0:
|
||||
self._scr_data.reset()
|
||||
return [self._preamble,MODE_BPSK,True,False]
|
||||
## ----- data frame ------
|
||||
success = True
|
||||
if self._frame_counter == -1: ## preamble mode
|
||||
if len(symbols) == 0:
|
||||
return [self._preamble,MODE_BPSK,success,False]
|
||||
else:
|
||||
success = self.decode_preamble(symbols)
|
||||
if self._pre_counter != 0:
|
||||
return [self._preamble,MODE_BPSK,success,False]
|
||||
else:
|
||||
self._frame_counter = 0
|
||||
self._scr_data.reset()
|
||||
return [self.get_next_data_frame(success),self._mode['ci'],success,success]
|
||||
else: ## data mode
|
||||
self._frame_counter += 1
|
||||
print('test:', symbols[self._mode['unknown']:], np.mean(np.real(symbols[self._mode['unknown']:])))
|
||||
if self._frame_counter < self._num_frames_per_block-2:
|
||||
success = np.bool(np.mean(np.real(symbols[self._mode['unknown']:])) > 0.7)
|
||||
return [self.get_next_data_frame(success),self._mode['ci'],success,success]
|
||||
|
||||
def get_next_data_frame(self, success):
|
||||
if self._frame_counter == self._num_frames_per_block:
|
||||
self._frame_counter = 0
|
||||
scramble_for_frame = n_psk(8, np.array([self._scr_data.next()
|
||||
|
@ -142,34 +157,12 @@ class PhysicalLayer(object):
|
|||
idx_d1d2 = self._frame_counter - self._num_frames_per_block + 2;
|
||||
a['symb'][n_unknown :n_unknown+ 8] *= n_psk(2, WALSH[self._d1d2[idx_d1d2]][:])
|
||||
a['symb'][n_unknown+8:n_unknown+16] *= n_psk(2, WALSH[self._d1d2[idx_d1d2]][:])
|
||||
if not success:
|
||||
self._frame_counter = -1
|
||||
self._pre_counter = -1
|
||||
return a
|
||||
|
||||
self._frame_counter += 1
|
||||
return [a, self._mode['ci'],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))
|
||||
success,doppler = False,0
|
||||
if self._frame_counter == -1: ## -- preamble ----
|
||||
success,doppler = self.get_doppler_from_preamble(symbols, iq_samples)
|
||||
if len(symbols) != 0:
|
||||
success = self.decode_preamble(symbols)
|
||||
if self._pre_counter == 0:
|
||||
self._frame_counter = 0
|
||||
print('pre_counter', self._pre_counter,
|
||||
'mode', self._mode)
|
||||
else: ## ------------------------ data frame ----
|
||||
print(self._frame_counter,symbols, np.mean(np.abs(symbols)))
|
||||
success = np.mean(np.abs(symbols[0:20])) > 0.5
|
||||
if not success:
|
||||
self._frame_counter = -1
|
||||
self._pre_counter = -1
|
||||
return success,doppler
|
||||
|
||||
def get_doppler_from_preamble(self, symbols, iq_samples):
|
||||
def get_doppler(self, iq_samples):
|
||||
"""quality check and doppler estimation for preamble"""
|
||||
success,doppler = True,0
|
||||
if len(iq_samples) != 0:
|
||||
|
@ -177,21 +170,25 @@ class PhysicalLayer(object):
|
|||
zp = np.array([z for z in PhysicalLayer.get_preamble()['symb']
|
||||
for _ in range(sps)], dtype=np.complex64)
|
||||
## find starting point
|
||||
cc = np.correlate(iq_samples, zp[0:3*32*sps])
|
||||
_,_zp = self.get_preamble_z()
|
||||
cc = np.correlate(iq_samples, _zp) ##zp[0:3*32*sps])
|
||||
imax = np.argmax(np.abs(cc[0:2*32*sps]))
|
||||
pks = cc[(imax, imax+3*32*sps),]
|
||||
tpks = cc[imax+3*16*sps:imax+5*16*sps]
|
||||
print('imax=', imax, 'apks=',np.abs(pks),
|
||||
np.mean(np.abs(pks)), np.mean(np.abs(tpks)), np.abs(tpks))
|
||||
success = np.mean(np.abs(pks)) > 2*np.mean(np.abs(tpks))
|
||||
doppler = np.diff(np.unwrap(np.angle(pks)))[0]/(3*32) if success else 0
|
||||
apks = np.abs(cc[(imax, imax+3*32*sps),])
|
||||
tpks = np.abs(cc[imax+3*16*sps:imax+5*16*sps])
|
||||
print('imax=', imax, 'apks=',apks,
|
||||
np.mean(apks), np.mean(tpks))
|
||||
success = np.bool(np.mean(apks) > 5*np.mean(tpks) and
|
||||
apks[0]/apks[1] > 0.5 and
|
||||
apks[0]/apks[1] < 2.0)
|
||||
if success:
|
||||
idx = np.arange(32*sps)
|
||||
pks = [np.correlate(iq_samples[imax+i*32*sps+idx],
|
||||
zp[i*32*sps+idx])[0]
|
||||
zp[ i*32*sps+idx])[0]
|
||||
for i in range(9)]
|
||||
doppler = freq_est(pks)/32
|
||||
print('success=', success, 'doppler=', doppler)
|
||||
doppler = freq_est(pks)/(32*sps)
|
||||
print('success=', success, 'doppler=', doppler,
|
||||
np.abs(np.array(pks)),
|
||||
np.angle(np.array(pks)))
|
||||
return success,doppler
|
||||
|
||||
def decode_preamble(self, symbols):
|
||||
|
@ -209,6 +206,9 @@ class PhysicalLayer(object):
|
|||
self._num_frames_per_block = self._block_len/self._frame_len;
|
||||
return True
|
||||
|
||||
def set_mode(self, _):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def get_preamble():
|
||||
"""preamble symbols + scrambler"""
|
||||
|
@ -217,12 +217,11 @@ class PhysicalLayer(object):
|
|||
dtype=[('symb', np.complex64),
|
||||
('scramble', np.complex64)])
|
||||
|
||||
@staticmethod
|
||||
def get_preamble_z(sps):
|
||||
def get_preamble_z(self):
|
||||
"""preamble symbols for preamble correlation"""
|
||||
a = PhysicalLayer.get_preamble()
|
||||
return np.array([z for z in a['symb'][0:32*3]
|
||||
for _ in range(sps)])
|
||||
return 0,np.array([z for z in a['symb'][0:3*32]
|
||||
for _ in range(self._sps)])
|
||||
|
||||
if __name__ == '__main__':
|
||||
def gen_data_scramble():
|
||||
|
@ -238,20 +237,23 @@ if __name__ == '__main__':
|
|||
a[i] = s&7;
|
||||
return a
|
||||
|
||||
p=PhysicalLayer(5)
|
||||
z1=np.array([x for x in PRE_SYMBOLS for _ in range(5)])
|
||||
z2=np.array([x for x in PRE_SCRAMBLE for _ in range(5)])
|
||||
z=z1*z2
|
||||
|
||||
sps = 5;
|
||||
p=PhysicalLayer(sps)
|
||||
z1=np.array([x for x in PRE_SYMBOLS for _ in range(sps)])
|
||||
z2=np.array([x for x in PRE_SCRAMBLE for _ in range(sps)])
|
||||
z=z1*z2;
|
||||
_,_z=p.get_preamble_z()
|
||||
print(all(z[0:3*32*sps]==_z[0:3*32*sps]))
|
||||
for i in range(3):
|
||||
print(i, all(z[32*5*i:32*5*(i+1)] == z[32*5*(3+i):32*5*(3+i+1)]))
|
||||
print(i, all(z[32*sps*i:32*sps*(i+1)] == z[32*sps*(3+i):32*sps*(3+i+1)]))
|
||||
|
||||
print(np.sum(np.sum(z[0:32*5] * np.conj(z[32*5*3:32*5*4]))))
|
||||
print(WALSH[1][:])
|
||||
print(sum(WALSH[1][:]*(1<<np.array(range(7,-1,-1)))))
|
||||
print(FROM_WALSH)
|
||||
print(gen_data_scramble())
|
||||
#print(np.sum(np.sum(z[0:32*5] * np.conj(z[32*5*3:32*5*4]))))
|
||||
#print(WALSH[1][:])
|
||||
#print(sum(WALSH[1][:]*(1<<np.array(range(7,-1,-1)))))
|
||||
#print(FROM_WALSH)
|
||||
#print(gen_data_scramble())
|
||||
|
||||
s=ScrambleData()
|
||||
print([s.next() for _ in range(160)])
|
||||
print([s.next() for _ in range(160)])
|
||||
#print([s.next() for _ in range(160)])
|
||||
#print([s.next() for _ in range(160)])
|
||||
#print(np.round(np.angle(PRE_SYMBOLS*PRE_SCRAMBLE)/np.pi*4))
|
||||
|
|
|
@ -44,8 +44,8 @@ QAM64=np.array(
|
|||
range(64)), CONST_DTYPE)
|
||||
|
||||
## for test
|
||||
QAM64 = QAM64[(7,3,24,56,35,39,60,28),]
|
||||
QAM64['symbols'] = [1, 0, 2, 6, 4, 5, 7, 3]
|
||||
#QAM64 = QAM64[(7,3,24,56,35,39,60,28),]
|
||||
#QAM64['symbols'] = [1, 0, 2, 6, 4, 5, 7, 3]
|
||||
|
||||
## ---- constellation indices ---------------------------------------------------
|
||||
MODE_BPSK = 0
|
||||
|
@ -142,118 +142,111 @@ class PhysicalLayer(object):
|
|||
def get_constellations(self):
|
||||
return self._constellations
|
||||
|
||||
def get_frame(self):
|
||||
def get_next_frame(self, symbols):
|
||||
"""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 if the processing should continue
|
||||
[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:
|
||||
print('-------------------- get_frame --------------------', self._frame_counter)
|
||||
success = True
|
||||
if self._frame_counter == -1: ## ---- preamble
|
||||
self._preamble_offset = 0
|
||||
return [self._preamble,MODE_BPSK,True,False]
|
||||
## ----- (re)inserted preamble ------
|
||||
if self._frame_counter == 0:
|
||||
self.a = self.make_reinserted_preamble(self._preamble_offset)
|
||||
return [self.a, MODE_QPSK,False,False]
|
||||
if self._frame_counter >= 1:
|
||||
self.a = self.make_data_frame()
|
||||
return [self.a, self._constellation_index,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,doppler = False,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
|
||||
elif self._frame_counter == 0: ## -- reinserted preamble ----
|
||||
## decode D0,D1,D2
|
||||
idx = np.arange(13)
|
||||
z = np.array([np.mean(symbols[32+13*i+idx]) for i in range(3)])
|
||||
d0d1d2 = map(np.uint8, np.mod(np.round(np.angle(z)/np.pi*2),4))
|
||||
dibits = [TO_DIBIT[idx] for idx in d0d1d2]
|
||||
self._mode = {'rate': tuple([x[0] for x in dibits]),
|
||||
'interleaver': tuple([x[1] for x in dibits])}
|
||||
print('======== rate,interleaver:',
|
||||
TO_RATE[self._mode['rate']],
|
||||
TO_INTERLEAVER[self._mode['interleaver']])
|
||||
rate_info = TO_RATE[self._mode['rate']]
|
||||
self._constellation_index = rate_info['ci']
|
||||
print('constellation index', self._constellation_index)
|
||||
scr = ScrambleData()
|
||||
iscr = [scr.next(rate_info['bits_per_symbol']) for _ in range(256)]
|
||||
if rate_info['ci'] > MODE_8PSK:
|
||||
self._data_scramble = np.ones(256, dtype=np.complex64)
|
||||
else:
|
||||
constell = self._constellations[rate_info['ci']]
|
||||
self._data_scramble = constell[iscr]
|
||||
self._frame_counter += 1
|
||||
success = True
|
||||
elif self._frame_counter <=72: ## -- data -------------------
|
||||
print(np.abs(symbols[:16]), symbols[-31:], np.mean(symbols[-31:]))
|
||||
success = np.abs(np.mean(symbols[-31:])) > 0.5
|
||||
if success:
|
||||
self._frame_counter += 1
|
||||
else:
|
||||
self._frame_counter = -1
|
||||
else: ## ------------------------ re-inserted preamble -------
|
||||
## TODO
|
||||
for s in symbols:
|
||||
print(s)
|
||||
success = False
|
||||
self._frame_counter = -1
|
||||
return success,doppler
|
||||
return [self._preamble,MODE_BPSK,success,False]
|
||||
|
||||
def get_doppler_from_preamble(self, symbols, iq_samples):
|
||||
frame_counter_mod = self._frame_counter%72
|
||||
if frame_counter_mod == 0: ## --- re-inserted preamble
|
||||
self._frame_counter += 1
|
||||
success = self.get_preamble_quality(symbols)
|
||||
return [self.make_reinserted_preamble(self._preamble_offset,success),MODE_QPSK,success,False]
|
||||
|
||||
if frame_counter_mod >= 1: ## ---- data frames
|
||||
got_reinserted_preamble = frame_counter_mod == 1
|
||||
self._frame_counter += 1
|
||||
if got_reinserted_preamble:
|
||||
success = self.decode_reinserted_preamble(symbols)
|
||||
else:
|
||||
success = self.get_data_frame_quality(symbols)
|
||||
return [self.make_data_frame(success),self._constellation_index,success,not got_reinserted_preamble]
|
||||
|
||||
def get_doppler(self, iq_samples):
|
||||
"""quality check and doppler estimation for preamble"""
|
||||
success,doppler = True,0
|
||||
if len(iq_samples) != 0:
|
||||
sps = self._sps
|
||||
idx = np.arange(23*sps)
|
||||
zp = self.get_preamble_z(self._sps)
|
||||
_,zp = self.get_preamble_z()
|
||||
cc = np.correlate(iq_samples, zp[idx])
|
||||
imax = np.argmax(np.abs(cc[0:23*sps]))
|
||||
pks = [np.correlate(iq_samples[imax+i*23*sps+idx],
|
||||
zp[i*23*sps+idx])[0]
|
||||
for i in range(7)]
|
||||
success = np.mean(np.abs(pks)) > 2*np.mean(np.abs(cc[imax+11*sps+range(-sps,sps)]))
|
||||
for i in range(8)]
|
||||
success = np.bool(np.mean(np.abs(pks)) > 2*np.mean(np.abs(cc[imax+11*sps+range(-sps,sps)])))
|
||||
print('test:',imax, np.mean(np.abs(pks)), np.mean(np.abs(cc[imax+11*sps+range(-sps,sps)])))
|
||||
if success:
|
||||
print('doppler apks', np.abs(pks))
|
||||
print('doppler ppks', np.angle(pks),
|
||||
np.diff(np.unwrap(np.angle(pks)))/23,
|
||||
np.mean(np.diff(np.unwrap(np.angle(pks)))/23))
|
||||
doppler = freq_est(pks[1:])/23;
|
||||
doppler = freq_est(pks)/(23*sps);
|
||||
print('success=', success, 'doppler=', doppler)
|
||||
return success,doppler
|
||||
|
||||
def make_reinserted_preamble(self, offset):
|
||||
def set_mode(self, mode):
|
||||
pass
|
||||
|
||||
def get_preamble_quality(self, symbols):
|
||||
return np.bool(np.abs(np.mean(symbols[-40:])) > 0.5)
|
||||
|
||||
def get_data_frame_quality(self, symbols):
|
||||
return np.bool(np.abs(np.mean(symbols[-31:])) > 0.5)
|
||||
|
||||
def decode_reinserted_preamble(self, symbols):
|
||||
## decode D0,D1,D2
|
||||
idx = np.arange(13)
|
||||
z = np.array([np.mean(symbols[32+13*i+idx]) for i in range(3)])
|
||||
d0d1d2 = map(np.uint8, np.mod(np.round(np.angle(z)/np.pi*2),4))
|
||||
dibits = [TO_DIBIT[idx] for idx in d0d1d2]
|
||||
self._mode = {'rate': tuple([x[0] for x in dibits]),
|
||||
'interleaver': tuple([x[1] for x in dibits])}
|
||||
print('======== rate,interleaver:',
|
||||
TO_RATE[self._mode['rate']],
|
||||
TO_INTERLEAVER[self._mode['interleaver']])
|
||||
rate_info = TO_RATE[self._mode['rate']]
|
||||
print('rate_info', rate_info)
|
||||
self._constellation_index = rate_info['ci']
|
||||
print('constellation index', self._constellation_index)
|
||||
scr = ScrambleData()
|
||||
iscr = [scr.next(rate_info['bits_per_symbol']) for _ in range(256)]
|
||||
if rate_info['ci'] > MODE_8PSK:
|
||||
self._data_scramble = np.ones(256, dtype=np.complex64)
|
||||
else:
|
||||
constell = self._constellations[rate_info['ci']]
|
||||
self._data_scramble = constell[iscr]['points']
|
||||
success = True ## TODO
|
||||
return success
|
||||
|
||||
def make_reinserted_preamble(self, offset, success):
|
||||
""" offset= 0 -> 1st reinserted preamble
|
||||
offset=-72 -> all following reinserted preambles"""
|
||||
print('make_reinserted_preamble', offset, success)
|
||||
a=np.array(zip(REINSERTED_PREAMBLE[offset:],
|
||||
REINSERTED_PREAMBLE[offset:]),
|
||||
dtype=[('symb', np.complex64),
|
||||
('scramble', np.complex64)])
|
||||
a['symb'][-72:-72+3*13] = 0 ## D0,D1,D2
|
||||
if not success:
|
||||
sefl._frame_counter = -1
|
||||
return a
|
||||
def make_data_frame(self):
|
||||
|
||||
def make_data_frame(self, success):
|
||||
self._preamble_offset = -72 ## all following reinserted preambles start at index -72
|
||||
a=np.zeros(256+31, dtype=[('symb', np.complex64),
|
||||
('scramble', np.complex64)])
|
||||
a['scramble'][:256] = self._data_scramble
|
||||
n = self._frame_counter -1
|
||||
n = (self._frame_counter-2)%72
|
||||
m = n%18
|
||||
if m == 0:
|
||||
cnt = n//18
|
||||
|
@ -261,6 +254,8 @@ class PhysicalLayer(object):
|
|||
print('new mini-probe signs n=',n,'m=',m,self._mp)
|
||||
a['symb'][256:] = MINI_PROBE[self._mp[m]]
|
||||
a['scramble'][256:] = MINI_PROBE[self._mp[m]]
|
||||
if not success:
|
||||
self._frame_counter = -1
|
||||
return a
|
||||
|
||||
@staticmethod
|
||||
|
@ -270,10 +265,10 @@ class PhysicalLayer(object):
|
|||
PREAMBLE),
|
||||
dtype=[('symb', np.complex64),
|
||||
('scramble', np.complex64)])
|
||||
@staticmethod
|
||||
def get_preamble_z(sps):
|
||||
|
||||
def get_preamble_z(self):
|
||||
"""preamble symbols for preamble correlation"""
|
||||
return np.array([z for z in PREAMBLE for _ in range(sps)])
|
||||
return 2,np.array([z for z in PREAMBLE for _ in range(self._sps)])
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(PREAMBLE)
|
||||
|
|
|
@ -12,7 +12,7 @@ class PhysicalLayer(object):
|
|||
def __init__(self, sps):
|
||||
"""intialization"""
|
||||
self._sps = sps
|
||||
self._mode = self.MODE_BPSK
|
||||
self._mode = self.MODE_QPSK
|
||||
self._frame_counter = 0
|
||||
self._is_first_frame = True
|
||||
self._constellations = [self.make_psk(2, [0,1]),
|
||||
|
@ -29,50 +29,53 @@ class PhysicalLayer(object):
|
|||
def get_constellations(self):
|
||||
return self._constellations
|
||||
|
||||
def get_frame(self):
|
||||
def get_next_frame(self, symbols):
|
||||
"""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 if the processing should continue
|
||||
[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,False] if self.is_preamble() else [self._data,self._mode,False,True]
|
||||
## print('-------------------- get_frame --------------------', self._frame_counter, len(symbols))
|
||||
if len(symbols) == 0: ## 1st preamble
|
||||
self._frame_counter = 0
|
||||
|
||||
def get_doppler(self, symbols, iq_samples):
|
||||
success,frame_description = True,[]
|
||||
if (self._frame_counter%2) == 0:
|
||||
frame_description = [self._preamble,self.MODE_BPSK,success,False]
|
||||
else:
|
||||
idx = range(30,80)
|
||||
z = symbols[idx]*np.conj(self._preamble['symb'][idx])
|
||||
## print('quality_preamble',np.sum(np.real(z)<0), symbols[idx])
|
||||
success = np.bool(np.sum(np.real(z)<0) < 30)
|
||||
frame_description = [self._data,self._mode,success,True]
|
||||
|
||||
self._frame_counter += 1
|
||||
return frame_description
|
||||
|
||||
def get_doppler(self, 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))
|
||||
success,doppler = self.quality_preamble(symbols,iq_samples) if self.is_preamble() else self.quality_data(symbols)
|
||||
if len(symbols) != 0:
|
||||
self._frame_counter = (self._frame_counter+1)&1 if success else 0
|
||||
self._is_first_frame = not success
|
||||
## print('-------------------- get_doppler --------------------', self._frame_counter,len(iq_samples))
|
||||
success,doppler = False,0
|
||||
if len(iq_samples) == 0:
|
||||
return success,doppler
|
||||
|
||||
sps = self._sps
|
||||
zp = np.array([x for x in self._preamble['symb'][9:40]
|
||||
for _ in range(sps)], dtype=np.complex64)
|
||||
cc = np.correlate(iq_samples, zp)
|
||||
imax = np.argmax(np.abs(cc[0:18*sps]))
|
||||
pks = cc[(imax,imax+31*sps),]
|
||||
tpks = cc[imax+15*sps:imax+16*sps]
|
||||
## print('doppler: ', np.abs(pks), np.abs(tpks))
|
||||
success = np.bool(np.mean(np.abs(pks)) > 5*np.mean(np.abs(tpks)))
|
||||
doppler = np.diff(np.unwrap(np.angle(pks)))[0]/31/self._sps if success else 0
|
||||
return success,doppler
|
||||
|
||||
def is_preamble(self):
|
||||
return self._frame_counter == 0
|
||||
|
||||
def quality_preamble(self, symbols, iq_samples):
|
||||
"""quality check and doppler estimation for preamble"""
|
||||
success = True
|
||||
doppler = 0
|
||||
if len(iq_samples) != 0:
|
||||
sps = self._sps
|
||||
zp = np.array([x for x in self._preamble['symb'][9:40]
|
||||
for _ in range(sps)], dtype=np.complex64)
|
||||
cc = np.correlate(iq_samples, zp)
|
||||
imax = np.argmax(np.abs(cc[0:18*sps]))
|
||||
pks = cc[(imax,imax+31*sps),]
|
||||
tpks = cc[imax+15*sps:imax+16*sps]
|
||||
success = np.mean(np.abs(pks)) > 2*np.mean(np.abs(tpks))
|
||||
doppler = np.diff(np.unwrap(np.angle(pks)))[0]/31 if success else 0
|
||||
if len(symbols) != 0:
|
||||
idx = range(30,80) if self._is_first_frame else range(80)
|
||||
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
|
||||
return success,doppler
|
||||
|
||||
def quality_data(self, s):
|
||||
"""quality check for the data frame"""
|
||||
known_symbols = np.mod(range(176),48)>=32
|
||||
|
@ -80,6 +83,11 @@ class PhysicalLayer(object):
|
|||
success = np.sum(np.real(s[known_symbols])<0) < 20
|
||||
return success,0 ## no doppler estimate for data frames
|
||||
|
||||
def get_preamble_z(self):
|
||||
"""preamble symbols for preamble correlation"""
|
||||
a = PhysicalLayer.get_preamble()
|
||||
return 2,np.array([z for z in a['symb'][0:31] for _ in range(self._sps)])
|
||||
|
||||
@staticmethod
|
||||
def get_preamble():
|
||||
"""preamble symbols + scrambler(=1)"""
|
||||
|
@ -117,7 +125,7 @@ class PhysicalLayer(object):
|
|||
@staticmethod
|
||||
def make_psk(n, gray_code):
|
||||
"""generates n-PSK constellation data"""
|
||||
c = np.zeros(n, dtype=[('points', np.complex64), ('symbols', np.uint8)])
|
||||
c = np.zeros(n, dtype=[('points', np.complex64), ('symbols', np.int32)])
|
||||
c['points'] = np.exp(2*np.pi*1j*np.arange(n)/n)
|
||||
c['symbols'] = gray_code
|
||||
return c
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import numpy as np
|
||||
|
||||
CONST_DTYPE=np.dtype([('points', np.complex64),
|
||||
('symbols', np.uint8)])
|
||||
('symbols', np.int32)])
|
||||
|
||||
def n_psk(n,x):
|
||||
"""n-ary PSK constellation"""
|
||||
|
|
91
python/physical_layer_driver.py
Normal file
91
python/physical_layer_driver.py
Normal file
|
@ -0,0 +1,91 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2018 hcab14@gmail.com.
|
||||
#
|
||||
# This is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This software is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this software; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
|
||||
import importlib
|
||||
from gnuradio import blocks
|
||||
from gnuradio import digital
|
||||
from gnuradio import filter
|
||||
from gnuradio import gr
|
||||
import pmt
|
||||
import digitalhf
|
||||
import digitalhf.physical_layer
|
||||
|
||||
class physical_layer_driver(gr.hier_block2):
|
||||
"""
|
||||
docstring for block physical_layer_driver
|
||||
"""
|
||||
def __init__(self, samp_rate,sps,alpha,mu,nB,nF,nW,description_name,mode):
|
||||
gr.hier_block2.__init__(self,
|
||||
"physical_layer_driver",
|
||||
gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
|
||||
gr.io_signature(2, 2, gr.sizeof_gr_complex)) # Output signature
|
||||
|
||||
self._sps = sps
|
||||
self._alpha = alpha
|
||||
self._mu = mu
|
||||
self._nB = nB
|
||||
self._nF = nF
|
||||
self._nW = nW
|
||||
|
||||
m = importlib.import_module('digitalhf.physical_layer.'+description_name)
|
||||
self._physical_layer_driver_description = m.PhysicalLayer(sps)
|
||||
self._physical_layer_driver_description.set_mode(mode)
|
||||
|
||||
## TODO: get rrc tap information from physical layer description
|
||||
self._rrc_taps = filter.firdes.root_raised_cosine(1.0, samp_rate, samp_rate/sps, 0.35, 11*sps)
|
||||
preamble_offset,preamble_samples = self._physical_layer_driver_description.get_preamble_z()
|
||||
preamble_length = sps*len(self._physical_layer_driver_description.get_preamble())
|
||||
self._rrc_filter = filter.fir_filter_ccc(1, (self._rrc_taps))
|
||||
self._corr_est = digital.corr_est_cc((preamble_samples.tolist()), sps, preamble_offset, 0.5)
|
||||
self._doppler_correction = digitalhf.doppler_correction_cc(preamble_length, len(preamble_samples))
|
||||
self._adaptive_filter = digitalhf.adaptive_dfe(sps, nB, nF, nW, mu, alpha)
|
||||
self._msg_proxy = digitalhf.msg_proxy(self._physical_layer_driver_description)
|
||||
self.connect((self, 0),
|
||||
(self._rrc_filter, 0),
|
||||
(self._corr_est, 0),
|
||||
(self._doppler_correction, 0),
|
||||
(self._adaptive_filter, 0),
|
||||
(self, 0))
|
||||
self.connect((self._corr_est, 1), ## correlation
|
||||
(self, 1))
|
||||
|
||||
self.msg_connect((self._doppler_correction, 'doppler'), (self._msg_proxy, 'doppler'))
|
||||
self.msg_connect((self._msg_proxy, 'doppler'), (self._doppler_correction, 'doppler'))
|
||||
|
||||
self.msg_connect((self._adaptive_filter, 'frame_info'), (self._msg_proxy, 'frame_info'))
|
||||
self.msg_connect((self._msg_proxy, 'frame_info'), (self._adaptive_filter, 'frame_info'))
|
||||
|
||||
constellations_data = self._physical_layer_driver_description.get_constellations()
|
||||
constellations_msg = pmt.to_pmt([{'idx': idx, 'points': c['points'], 'symbols': c['symbols']}
|
||||
for (idx,c) in enumerate(constellations_data)])
|
||||
self._adaptive_filter.to_basic_block()._post(pmt.intern('constellations'), constellations_msg)
|
||||
|
||||
self.message_port_register_hier_out('soft_dec')
|
||||
self.msg_connect((self._adaptive_filter, 'soft_dec'), (self, 'soft_dec'))
|
||||
|
||||
def set_mu(self, mu):
|
||||
self._adaptive_filter.set_mu(mu)
|
||||
|
||||
def set_alpha(self, alpha):
|
||||
self._adaptive_filter.set_alpha(alpha)
|
||||
|
||||
def set_mode(self, mode):
|
||||
self._physical_layer_driver_description.set_mode(mode)
|
41
python/qa_doppler_correction_cc.py
Executable file
41
python/qa_doppler_correction_cc.py
Executable file
|
@ -0,0 +1,41 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2018 hcab14@gmail.com.
|
||||
#
|
||||
# This is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This software is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this software; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
|
||||
from gnuradio import gr, gr_unittest
|
||||
from gnuradio import blocks
|
||||
import digitalhf.digitalhf_swig as digitalhf
|
||||
|
||||
|
||||
class qa_doppler_correction_cc(gr_unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.tb = gr.top_block()
|
||||
|
||||
def tearDown(self):
|
||||
self.tb = None
|
||||
|
||||
def test_001_t(self):
|
||||
# set up fg
|
||||
self.tb.run()
|
||||
# check data
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
gr_unittest.run(qa_doppler_correction_cc, "qa_doppler_correction_cc.xml")
|
41
python/qa_msg_proxy.py
Executable file
41
python/qa_msg_proxy.py
Executable file
|
@ -0,0 +1,41 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2018 hcab14@gmail.com.
|
||||
#
|
||||
# This is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This software is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this software; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
|
||||
from gnuradio import gr, gr_unittest
|
||||
from gnuradio import blocks
|
||||
from physical_layer_driver import physical_layer_driver
|
||||
|
||||
|
||||
class qa_msg_proxy(gr_unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.tb = gr.top_block()
|
||||
|
||||
def tearDown(self):
|
||||
self.tb = None
|
||||
|
||||
def test_001_t(self):
|
||||
# set up fg
|
||||
self.tb.run()
|
||||
# check data
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
gr_unittest.run(qa_msg_proxy, "qa_msg_proxy.xml")
|
41
python/qa_physical_layer_driver.py
Executable file
41
python/qa_physical_layer_driver.py
Executable file
|
@ -0,0 +1,41 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2018 hcab14@gmail.com.
|
||||
#
|
||||
# This is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This software is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this software; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
|
||||
from gnuradio import gr, gr_unittest
|
||||
from gnuradio import blocks
|
||||
from physical_layer import physical_layer
|
||||
|
||||
|
||||
class qa_physical_layer_driver(gr_unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.tb = gr.top_block()
|
||||
|
||||
def tearDown(self):
|
||||
self.tb = None
|
||||
|
||||
def test_001_t(self):
|
||||
# set up fg
|
||||
self.tb.run()
|
||||
# check data
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
gr_unittest.run(qa_physical_layer_driver, "qa_physical_layer_driver.xml")
|
|
@ -9,7 +9,10 @@
|
|||
|
||||
%{
|
||||
#include "digitalhf/adaptive_dfe.h"
|
||||
#include "digitalhf/doppler_correction_cc.h"
|
||||
%}
|
||||
|
||||
%include "digitalhf/adaptive_dfe.h"
|
||||
GR_SWIG_BLOCK_MAGIC2(digitalhf, adaptive_dfe);
|
||||
%include "digitalhf/doppler_correction_cc.h"
|
||||
GR_SWIG_BLOCK_MAGIC2(digitalhf, doppler_correction_cc);
|
||||
|
|
Loading…
Reference in a new issue