aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNao Pross <np@0hm.ch>2021-12-03 23:46:33 +0100
committerNao Pross <np@0hm.ch>2021-12-03 23:46:33 +0100
commit13a2fda61a5cb1e6d3f807d0acda42c45e128434 (patch)
tree523cb1bc7c48bccec82c1a2366992f07ed41ca23
parentFix network sink block (diff)
downloadFading-13a2fda61a5cb1e6d3f807d0acda42c45e128434.tar.gz
Fading-13a2fda61a5cb1e6d3f807d0acda42c45e128434.zip
Fix correlation peak detector and add frame_start tags
-rw-r--r--tests/correlator/correlator.grc502
-rwxr-xr-xtests/correlator/correlator.py17
-rw-r--r--tests/correlator/epy_block_0.py32
3 files changed, 157 insertions, 394 deletions
diff --git a/tests/correlator/correlator.grc b/tests/correlator/correlator.grc
index beea007..c34e5a9 100644
--- a/tests/correlator/correlator.grc
+++ b/tests/correlator/correlator.grc
@@ -36,15 +36,15 @@ blocks:
id: variable
parameters:
comment: ''
- value: '[(-1.4142135623730951-1.4142135623730951j), (1.4142135623730951-1.4142135623730951j),
+ value: .5 * np.array([(-1.4142135623730951-1.4142135623730951j), (1.4142135623730951-1.4142135623730951j),
(1.4142135623730951+1.4142135623730951j), (1.4142135623730951+1.4142135623730951j),
(-1.4142135623730951-1.4142135623730951j), (1.4142135623730951+1.4142135623730951j),
- (1.4142135623730951-1.4142135623730951j), (1.4142135623730951-1.4142135623730951j)]'
+ (1.4142135623730951-1.4142135623730951j), (1.4142135623730951-1.4142135623730951j)])
states:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [768, 1016.0]
+ coordinate: [792, 788.0]
rotation: 0
state: enabled
- name: const
@@ -101,7 +101,7 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [48, 440.0]
+ coordinate: [784, 1052.0]
rotation: 0
state: enabled
- name: rrc_taps
@@ -164,22 +164,6 @@ blocks:
coordinate: [224, 936.0]
rotation: 0
state: enabled
-- name: blocks_complex_to_magphase_0
- id: blocks_complex_to_magphase
- parameters:
- affinity: ''
- alias: ''
- comment: ''
- maxoutbuf: '0'
- minoutbuf: '0'
- vlen: '1'
- states:
- bus_sink: false
- bus_source: false
- bus_structure: null
- coordinate: [1040, 568.0]
- rotation: 0
- state: disabled
- name: blocks_complex_to_magphase_0_0
id: blocks_complex_to_magphase
parameters:
@@ -193,27 +177,9 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [1080, 1176.0]
+ coordinate: [1056, 984.0]
rotation: 0
state: enabled
-- name: blocks_multiply_const_vxx_0
- id: blocks_multiply_const_vxx
- parameters:
- affinity: ''
- alias: ''
- comment: ''
- const: 180 / 3.141592653589793
- maxoutbuf: '0'
- minoutbuf: '0'
- type: float
- vlen: '1'
- states:
- bus_sink: false
- bus_source: false
- bus_structure: null
- coordinate: [1288, 596.0]
- rotation: 0
- state: disabled
- name: blocks_multiply_const_vxx_0_0
id: blocks_multiply_const_vxx
parameters:
@@ -229,7 +195,7 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [1376, 1248.0]
+ coordinate: [1312, 1076.0]
rotation: 0
state: disabled
- name: blocks_null_sink_3
@@ -246,7 +212,7 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [1376, 1304.0]
+ coordinate: [1360, 1016.0]
rotation: 0
state: true
- name: blocks_null_source_0
@@ -294,7 +260,7 @@ blocks:
affinity: ''
alias: ''
comment: ''
- lengths: '[5, len(testvec)]'
+ lengths: '[0, len(testvec)]'
maxoutbuf: '0'
minoutbuf: '0'
num_inputs: '2'
@@ -307,6 +273,43 @@ blocks:
coordinate: [288, 256.0]
rotation: 0
state: enabled
+- name: blocks_tag_debug_0
+ id: blocks_tag_debug
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ display: 'True'
+ filter: '""'
+ name: ''
+ num_inputs: '1'
+ type: byte
+ vlen: '1'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [1208, 1164.0]
+ rotation: 0
+ state: disabled
+- name: blocks_tagged_stream_align_0
+ id: blocks_tagged_stream_align
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ lengthtagname: frame_start
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ type: byte
+ vlen: '1'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [928, 1260.0]
+ rotation: 0
+ state: true
- name: blocks_throttle_0
id: blocks_throttle
parameters:
@@ -354,7 +357,7 @@ blocks:
block_tags: 'False'
comment: ''
epsilon: '1.0'
- freq_offset: '0.0001'
+ freq_offset: '0.002'
maxoutbuf: '0'
minoutbuf: '0'
noise_voltage: '0.01'
@@ -429,18 +432,18 @@ blocks:
affinity: ''
alias: ''
comment: ''
- mark_delay: '0'
+ mark_delay: len(access_code_symbols) // 2
maxoutbuf: '0'
minoutbuf: '0'
sps: '1'
symbols: access_code_symbols
- threshold: '.8'
- threshold_method: digital.THRESHOLD_DYNAMIC
+ threshold: '.9'
+ threshold_method: digital.THRESHOLD_ABSOLUTE
states:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [768, 892.0]
+ coordinate: [792, 668.0]
rotation: 0
state: enabled
- name: digital_costas_loop_cc_0
@@ -458,7 +461,7 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [1080, 1000.0]
+ coordinate: [1104, 808.0]
rotation: 0
state: true
- name: digital_map_bb_0
@@ -476,7 +479,7 @@ blocks:
bus_structure: null
coordinate: [496, 1260.0]
rotation: 0
- state: bypassed
+ state: enabled
- name: digital_pfb_clock_sync_xxx_0
id: digital_pfb_clock_sync_xxx
parameters:
@@ -504,31 +507,33 @@ blocks:
id: epy_block
parameters:
_source_code: "import pmt\n\nimport numpy as np\nfrom gnuradio import gr\n\n\n\
- class blk(gr.sync_block):\n def __init__(self):\n gr.sync_block.__init__(\n\
- \ self,\n name='Phase and Frequency Correction',\n \
- \ in_sig=[np.complex64],\n out_sig=[np.complex64]\n \
- \ )\n\n # tags should not be propagated, we then output our own tags\n\
- \ self.set_tag_propagation_policy(gr.TPP_DONT)\n\n # because we\
- \ do block processing, we need to keep track of the last tag\n # of the\
- \ previous block to correct the first values of the next block\n self.last\
- \ = None\n self.lastfreq = 0\n\n def block_phase(self, start, end):\n\
- \ \"\"\"\n Compute a vector for the phase and frequency correction\
- \ for the samples\n between two tags (start and end).\n\n @param\
- \ start Tag where the samples should start to be corrected\n @param end\
- \ Tag where to stop correcting\n\n @return A vector of phase values\
- \ for each sample. If we call the ouput\n `phase' to correct\
- \ the samples between the start and end tags,\n TODO: finish\n\
- \ \"\"\"\n # compute number of samples in block\n nsamples\
- \ = end.offset - start.offset\n\n # unpack pmt values into start and\
- \ end phase\n sphase = pmt.to_python(start.value)\n ephase = pmt.to_python(end.value)\n\
+ class blk(gr.sync_block):\n \"\"\"\n Apply phase and frequency correction\
+ \ where there is a correlation peak tag.\n\n The correlation peak tags are\
+ \ NOT propagated, and instead replaced with a\n frame_start tag.\n \"\"\
+ \"\n def __init__(self):\n gr.sync_block.__init__(\n self,\n\
+ \ name='Phase and Frequency Correction',\n in_sig=[np.complex64],\n\
+ \ out_sig=[np.complex64]\n )\n\n # tags should not\
+ \ be propagated, we then output our own tags\n self.set_tag_propagation_policy(gr.TPP_DONT)\n\
+ \n # because we do block processing, we need to keep track of the last\
+ \ tag\n # of the previous block to correct the first values of the next\
+ \ block\n self.last = None\n self.lastfreq = 0\n\n def block_phase(self,\
+ \ start, end):\n \"\"\"\n Compute a vector for the phase and frequency\
+ \ correction for the samples\n between two tags (start and end).\n\n\
+ \ @param start Tag where the samples should start to be corrected\n \
+ \ @param end Tag where to stop correcting\n\n @return A vector\
+ \ of phase values for each sample. To correct the samples\n the\
+ \ data should be multiplied with np.exp(-1j * phase)\n \"\"\"\n \
+ \ # compute number of samples between tags\n nsamples = end.offset\
+ \ - start.offset\n\n # unpack pmt values into start and end phase\n \
+ \ sphase = pmt.to_python(start.value)\n ephase = pmt.to_python(end.value)\n\
\n # compute frequency offset between start and end\n phasediff\
\ = ephase - sphase\n\n if phasediff > np.pi:\n phasediff\
\ -= 2*np.pi\n\n elif phasediff < -np.pi:\n phasediff += 2*np.pi\n\
\n freq = phasediff / nsamples\n\n # save this one for the last\
\ block (see variable `end' in self.work)\n self.lastfreq = freq\n\n\
- \ # debugging\n print(f\"Correction for block of {nsamples:2d}\
+ \ # debugging\n print(f\"Correction for chunk of {nsamples:2d}\
\ samples is \" \\\n f\"sphase={sphase: .4f} rad and freq={freq*1e3:\
- \ .4f} milli rad / sample\")\n\n # compute block values\n return\
+ \ .4f} milli rad / sample\")\n\n # compute chunk values\n return\
\ sphase * np.ones(nsamples) + freq * np.arange(0, nsamples)\n\n def work(self,\
\ input_items, output_items):\n counter = self.nitems_written(0)\n\n\
\ # nicer aliases\n inp = input_items[0]\n out = output_items[0]\n\
@@ -540,14 +545,14 @@ blocks:
\ = {tags[-1].offset - tags[0].offset} \" \\\n f\"samples out of\
\ {len(inp)} input samples\")\n\n # compute \"the middle\"\n enough_samples\
\ = lambda pair: ((pair[1].offset - pair[0].offset) > 0)\n pairs = list(filter(enough_samples,\
- \ zip(tags, tags[1:])))\n blocks = [ self.block_phase(start, end) for\
- \ (start, end) in pairs ]\n middle = np.concatenate(blocks) if blocks\
+ \ zip(tags, tags[1:])))\n chunks = [ self.block_phase(start, end) for\
+ \ (start, end) in pairs ]\n middle = np.concatenate(chunks) if chunks\
\ else []\n\n # compute values at the end, we do not have informations\
- \ about the future\n # but we can use the frequency of the last block\
- \ to approximate\n nback = len(inp) - (tags[-1].offset - counter)\n \
- \ print(f\"Processing {nback} samples at the back of the buffer\")\n \
- \ end = np.ones(nback) * pmt.to_python(tags[-1].value) \\\n \
- \ + self.lastfreq * np.arange(0, nback)\n\n # compute the \"start\"\
+ \ about the future\n # but we can use the frequency of the last tag to\
+ \ approximate\n nback = len(inp) - (tags[-1].offset - counter)\n \
+ \ print(f\"Processing {nback} samples at the back of the buffer\")\n \
+ \ end = np.ones(nback) * pmt.to_python(tags[-1].value) \\\n \
+ \ + self.lastfreq * np.arange(0, nback)\n\n # compute the \"start\"\
, using the last tag from the previous call\n nfront = tags[0].offset\
\ - counter\n print(f\"Processing {nfront} samples at the front of the\
\ buffer\")\n start = self.block_phase(self.last, tags[0])[-nfront:]\
@@ -555,9 +560,11 @@ blocks:
\ # compute correction\n correction = np.exp(-1j * np.concatenate([start,\
\ middle, end]))\n length = len(correction)\n\n # write outputs\n\
\ out[:length] = inp[:length] * correction\n\n # save last tag\
- \ for next call\n self.last = tags[-1]\n\n # FIXME: should return\
- \ `length' but then the last sample is not\n # included and self.last\
- \ does something weird\n return len(out)\n"
+ \ for next call\n self.last = tags[-1]\n\n # add tags\n \
+ \ for tag in tags:\n self.add_item_tag(0, tag.offset, pmt.intern(\"\
+ frame_start\"), pmt.PMT_T)\n\n # FIXME: should return `length' but then\
+ \ the last sample is not\n # included and self.last does something\
+ \ weird\n return len(out)\n"
affinity: ''
alias: ''
comment: ''
@@ -565,11 +572,13 @@ blocks:
minoutbuf: '0'
states:
_io_cache: ('Phase and Frequency Correction', 'blk', [], [('0', 'complex', 1)],
- [('0', 'complex', 1)], '', [])
+ [('0', 'complex', 1)], '\n Apply phase and frequency correction where there
+ is a correlation peak tag.\n\n The correlation peak tags are NOT propagated,
+ and instead replaced with a\n frame_start tag.\n ', [])
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [1072, 912.0]
+ coordinate: [1088, 688.0]
rotation: 0
state: enabled
- name: epy_block_1
@@ -595,7 +604,7 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [920, 1264.0]
+ coordinate: [1232, 1264.0]
rotation: 0
state: true
- name: fir_filter_xxx_1
@@ -614,7 +623,7 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [776, 692.0]
+ coordinate: [784, 988.0]
rotation: 0
state: disabled
- name: import_0
@@ -630,6 +639,23 @@ blocks:
coordinate: [184, 12.0]
rotation: 0
state: true
+- name: note_0
+ id: note
+ parameters:
+ alias: ''
+ comment: 'THIS FLOWGRAPH MUST BE RUN
+
+ FROM THE TERMINAL BECAUSE
+
+ IT HAS A HUGE OUTPUT (PRINT)'
+ note: README
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [280, 12.0]
+ rotation: 0
+ state: true
- name: qtgui_const_sink_x_0
id: qtgui_const_sink_x
parameters:
@@ -719,7 +745,7 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [768, 592.0]
+ coordinate: [792, 572.0]
rotation: 0
state: enabled
- name: qtgui_const_sink_x_0_0
@@ -811,198 +837,9 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [1408, 964.0]
+ coordinate: [1416, 772.0]
rotation: 0
state: enabled
-- name: qtgui_const_sink_x_1
- id: qtgui_const_sink_x
- parameters:
- affinity: ''
- alias: ''
- alpha1: '.5'
- alpha10: '1.0'
- alpha2: '1.0'
- alpha3: '1.0'
- alpha4: '1.0'
- alpha5: '1.0'
- alpha6: '1.0'
- alpha7: '1.0'
- alpha8: '1.0'
- alpha9: '1.0'
- autoscale: 'True'
- axislabels: 'True'
- color1: '"blue"'
- color10: '"red"'
- color2: '"red"'
- color3: '"red"'
- color4: '"red"'
- color5: '"red"'
- color6: '"red"'
- color7: '"red"'
- color8: '"red"'
- color9: '"red"'
- comment: ''
- grid: 'True'
- gui_hint: 2,1,2,1
- label1: ''
- label10: ''
- label2: ''
- label3: ''
- label4: ''
- label5: ''
- label6: ''
- label7: ''
- label8: ''
- label9: ''
- legend: 'True'
- marker1: '9'
- marker10: '0'
- marker2: '0'
- marker3: '0'
- marker4: '0'
- marker5: '0'
- marker6: '0'
- marker7: '0'
- marker8: '0'
- marker9: '0'
- name: '"Cross Correlation"'
- nconnections: '1'
- size: '1024'
- style1: '2'
- style10: '0'
- style2: '0'
- style3: '0'
- style4: '0'
- style5: '0'
- style6: '0'
- style7: '0'
- style8: '0'
- style9: '0'
- tr_chan: '0'
- tr_level: '0.0'
- tr_mode: qtgui.TRIG_MODE_FREE
- tr_slope: qtgui.TRIG_SLOPE_POS
- tr_tag: '""'
- type: complex
- update_time: '0.10'
- width1: '1'
- width10: '1'
- width2: '1'
- width3: '1'
- width4: '1'
- width5: '1'
- width6: '1'
- width7: '1'
- width8: '1'
- width9: '1'
- xmax: '2'
- xmin: '-2'
- ymax: '2'
- ymin: '-2'
- states:
- bus_sink: false
- bus_source: false
- bus_structure: null
- coordinate: [1040, 480.0]
- rotation: 0
- state: disabled
-- name: qtgui_time_sink_x_0
- id: qtgui_time_sink_x
- parameters:
- affinity: ''
- alias: ''
- alpha1: '1.0'
- alpha10: '1.0'
- alpha2: '1.0'
- alpha3: '1.0'
- alpha4: '1.0'
- alpha5: '1.0'
- alpha6: '1.0'
- alpha7: '1.0'
- alpha8: '1.0'
- alpha9: '1.0'
- autoscale: 'True'
- axislabels: 'True'
- color1: blue
- color10: dark blue
- color2: red
- color3: green
- color4: black
- color5: cyan
- color6: magenta
- color7: yellow
- color8: dark red
- color9: dark green
- comment: ''
- ctrlpanel: 'False'
- entags: 'True'
- grid: 'False'
- gui_hint: 2,0,1,1
- label1: Signal 1
- label10: Signal 10
- label2: Signal 2
- label3: Signal 3
- label4: Signal 4
- label5: Signal 5
- label6: Signal 6
- label7: Signal 7
- label8: Signal 8
- label9: Signal 9
- legend: 'True'
- marker1: '-1'
- marker10: '-1'
- marker2: '-1'
- marker3: '-1'
- marker4: '-1'
- marker5: '-1'
- marker6: '-1'
- marker7: '-1'
- marker8: '-1'
- marker9: '-1'
- name: '""'
- nconnections: '1'
- size: '1024'
- srate: samp_rate
- stemplot: 'False'
- style1: '1'
- style10: '1'
- style2: '1'
- style3: '1'
- style4: '1'
- style5: '1'
- style6: '1'
- style7: '1'
- style8: '1'
- style9: '1'
- tr_chan: '0'
- tr_delay: '0'
- tr_level: '0.0'
- tr_mode: qtgui.TRIG_MODE_FREE
- tr_slope: qtgui.TRIG_SLOPE_POS
- tr_tag: '""'
- type: float
- update_time: '0.10'
- width1: '1'
- width10: '1'
- width2: '1'
- width3: '1'
- width4: '1'
- width5: '1'
- width6: '1'
- width7: '1'
- width8: '1'
- width9: '1'
- ylabel: XC Magnitude
- ymax: '20'
- ymin: '0'
- yunit: '""'
- states:
- bus_sink: false
- bus_source: false
- bus_structure: null
- coordinate: [1312, 480.0]
- rotation: 0
- state: disabled
- name: qtgui_time_sink_x_0_0
id: qtgui_time_sink_x
parameters:
@@ -1097,7 +934,7 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [1376, 1156.0]
+ coordinate: [1472, 964.0]
rotation: 0
state: enabled
- name: qtgui_time_sink_x_0_0_0
@@ -1194,7 +1031,7 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [1072, 788.0]
+ coordinate: [1096, 572.0]
rotation: 0
state: enabled
- name: qtgui_time_sink_x_1_0
@@ -1291,7 +1128,7 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [800, 320.0]
+ coordinate: [800, 172.0]
rotation: 0
state: enabled
- name: qtgui_time_sink_x_1_1
@@ -1388,104 +1225,7 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [768, 480.0]
- rotation: 0
- state: disabled
-- name: qtgui_time_sink_x_2
- id: qtgui_time_sink_x
- parameters:
- affinity: ''
- alias: ''
- alpha1: '1.0'
- alpha10: '1.0'
- alpha2: '1.0'
- alpha3: '1.0'
- alpha4: '1.0'
- alpha5: '1.0'
- alpha6: '1.0'
- alpha7: '1.0'
- alpha8: '1.0'
- alpha9: '1.0'
- autoscale: 'True'
- axislabels: 'True'
- color1: blue
- color10: dark blue
- color2: red
- color3: green
- color4: black
- color5: cyan
- color6: magenta
- color7: yellow
- color8: dark red
- color9: dark green
- comment: ''
- ctrlpanel: 'False'
- entags: 'True'
- grid: 'False'
- gui_hint: 3,0,1,1
- label1: Signal 1
- label10: Signal 10
- label2: Signal 2
- label3: Signal 3
- label4: Signal 4
- label5: Signal 5
- label6: Signal 6
- label7: Signal 7
- label8: Signal 8
- label9: Signal 9
- legend: 'True'
- marker1: '-1'
- marker10: '-1'
- marker2: '-1'
- marker3: '-1'
- marker4: '-1'
- marker5: '-1'
- marker6: '-1'
- marker7: '-1'
- marker8: '-1'
- marker9: '-1'
- name: '""'
- nconnections: '1'
- size: '1024'
- srate: samp_rate
- stemplot: 'False'
- style1: '1'
- style10: '1'
- style2: '1'
- style3: '1'
- style4: '1'
- style5: '1'
- style6: '1'
- style7: '1'
- style8: '1'
- style9: '1'
- tr_chan: '0'
- tr_delay: '0'
- tr_level: '0.0'
- tr_mode: qtgui.TRIG_MODE_FREE
- tr_slope: qtgui.TRIG_SLOPE_POS
- tr_tag: '""'
- type: float
- update_time: '0.10'
- width1: '1'
- width10: '1'
- width2: '1'
- width3: '1'
- width4: '1'
- width5: '1'
- width6: '1'
- width7: '1'
- width8: '1'
- width9: '1'
- ylabel: XC Phase
- ymax: '1'
- ymin: '-1'
- yunit: '""'
- states:
- bus_sink: false
- bus_source: false
- bus_structure: null
- coordinate: [1488, 580.0]
+ coordinate: [792, 484.0]
rotation: 0
state: disabled
- name: qtgui_time_sink_x_2_0
@@ -1582,7 +1322,7 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [1552, 1232.0]
+ coordinate: [1472, 1060.0]
rotation: 0
state: disabled
- name: virtual_sink_0
@@ -1608,7 +1348,7 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [1400, 828.0]
+ coordinate: [1416, 684.0]
rotation: 0
state: true
- name: virtual_source_0
@@ -1639,16 +1379,15 @@ blocks:
state: true
connections:
-- [blocks_complex_to_magphase_0, '0', qtgui_time_sink_x_0, '0']
-- [blocks_complex_to_magphase_0, '1', blocks_multiply_const_vxx_0, '0']
- [blocks_complex_to_magphase_0_0, '0', qtgui_time_sink_x_0_0, '0']
- [blocks_complex_to_magphase_0_0, '1', blocks_multiply_const_vxx_0_0, '0']
- [blocks_complex_to_magphase_0_0, '1', blocks_null_sink_3, '0']
-- [blocks_multiply_const_vxx_0, '0', qtgui_time_sink_x_2, '0']
- [blocks_multiply_const_vxx_0_0, '0', qtgui_time_sink_x_2_0, '0']
- [blocks_null_source_0, '0', blocks_stream_mux_0, '0']
-- [blocks_repack_bits_bb_0, '0', epy_block_1, '0']
+- [blocks_repack_bits_bb_0, '0', blocks_tagged_stream_align_0, '0']
- [blocks_stream_mux_0, '0', digital_constellation_modulator_0, '0']
+- [blocks_tagged_stream_align_0, '0', blocks_tag_debug_0, '0']
+- [blocks_tagged_stream_align_0, '0', epy_block_1, '0']
- [blocks_throttle_0, '0', virtual_sink_0, '0']
- [blocks_vector_source_x_0, '0', blocks_stream_mux_0, '1']
- [channels_channel_model_0, '0', blocks_throttle_0, '0']
@@ -1668,8 +1407,7 @@ connections:
- [digital_pfb_clock_sync_xxx_0, '0', digital_cma_equalizer_cc_0, '0']
- [epy_block_0, '0', qtgui_const_sink_x_0_0, '0']
- [epy_block_0, '0', virtual_sink_3, '0']
-- [fir_filter_xxx_1, '0', blocks_complex_to_magphase_0, '0']
-- [fir_filter_xxx_1, '0', qtgui_const_sink_x_1, '0']
+- [fir_filter_xxx_1, '0', blocks_complex_to_magphase_0_0, '0']
- [virtual_source_0, '0', digital_pfb_clock_sync_xxx_0, '0']
- [virtual_source_1, '0', digital_constellation_decoder_cb_0, '0']
diff --git a/tests/correlator/correlator.py b/tests/correlator/correlator.py
index 255010a..d9dedb2 100755
--- a/tests/correlator/correlator.py
+++ b/tests/correlator/correlator.py
@@ -85,7 +85,7 @@ class correlator(gr.top_block, Qt.QWidget):
self.rrc_taps = rrc_taps = firdes.root_raised_cosine(nfilts, nfilts, 1.0/float(sps), excess_bw, 45*nfilts)
self.revconj_access_code_symbols = revconj_access_code_symbols = [(1.4142135623730951+1.4142135623730951j), (1.4142135623730951+1.4142135623730951j), (1.4142135623730951-1.4142135623730951j), (-1.4142135623730951+1.4142135623730951j), (1.4142135623730951-1.4142135623730951j), (1.4142135623730951-1.4142135623730951j), (1.4142135623730951+1.4142135623730951j), (-1.4142135623730951+1.4142135623730951j)]
self.const = const = digital.constellation_qpsk().base()
- self.access_code_symbols = access_code_symbols = [(-1.4142135623730951-1.4142135623730951j), (1.4142135623730951-1.4142135623730951j), (1.4142135623730951+1.4142135623730951j), (1.4142135623730951+1.4142135623730951j), (-1.4142135623730951-1.4142135623730951j), (1.4142135623730951+1.4142135623730951j), (1.4142135623730951-1.4142135623730951j), (1.4142135623730951-1.4142135623730951j)]
+ self.access_code_symbols = access_code_symbols = .5 * np.array([(-1.4142135623730951-1.4142135623730951j), (1.4142135623730951-1.4142135623730951j), (1.4142135623730951+1.4142135623730951j), (1.4142135623730951+1.4142135623730951j), (-1.4142135623730951-1.4142135623730951j), (1.4142135623730951+1.4142135623730951j), (1.4142135623730951-1.4142135623730951j), (1.4142135623730951-1.4142135623730951j)])
##################################################
# Blocks
@@ -332,8 +332,9 @@ class correlator(gr.top_block, Qt.QWidget):
self.epy_block_1 = epy_block_1.blk()
self.epy_block_0 = epy_block_0.blk()
self.digital_pfb_clock_sync_xxx_0 = digital.pfb_clock_sync_ccf(sps, timing_loop_bw, rrc_taps, nfilts, 16, 1.5, 1)
+ self.digital_map_bb_0 = digital.map_bb([0, 1, 3, 2])
self.digital_costas_loop_cc_0 = digital.costas_loop_cc(2 * 3.141592653589793 / 100, 4, False)
- self.digital_corr_est_cc_0 = digital.corr_est_cc(access_code_symbols, 1, 0, .8, digital.THRESHOLD_DYNAMIC)
+ self.digital_corr_est_cc_0 = digital.corr_est_cc(access_code_symbols, 1, len(access_code_symbols) // 2, .9, digital.THRESHOLD_ABSOLUTE)
self.digital_constellation_modulator_0 = digital.generic_mod(
constellation=const,
differential=False,
@@ -346,14 +347,15 @@ class correlator(gr.top_block, Qt.QWidget):
self.digital_cma_equalizer_cc_0 = digital.cma_equalizer_cc(15, 1, .002, 1)
self.channels_channel_model_0 = channels.channel_model(
noise_voltage=0.01,
- frequency_offset=0.0001,
+ frequency_offset=0.002,
epsilon=1.0,
taps=[np.exp(1j * 30 / 180 * np.pi)],
noise_seed=243,
block_tags=False)
self.blocks_vector_source_x_0 = blocks.vector_source_b(testvec * 500, True, 1, [])
self.blocks_throttle_0 = blocks.throttle(gr.sizeof_gr_complex*1, samp_rate,True)
- self.blocks_stream_mux_0 = blocks.stream_mux(gr.sizeof_char*1, [5, len(testvec)])
+ self.blocks_tagged_stream_align_0 = blocks.tagged_stream_align(gr.sizeof_char*1, 'frame_start')
+ self.blocks_stream_mux_0 = blocks.stream_mux(gr.sizeof_char*1, [0, len(testvec)])
self.blocks_repack_bits_bb_0 = blocks.repack_bits_bb(2, 8, "", False, gr.GR_MSB_FIRST)
self.blocks_null_source_0 = blocks.null_source(gr.sizeof_char*1)
self.blocks_null_sink_3 = blocks.null_sink(gr.sizeof_float*1)
@@ -367,14 +369,15 @@ class correlator(gr.top_block, Qt.QWidget):
self.connect((self.blocks_complex_to_magphase_0_0, 1), (self.blocks_null_sink_3, 0))
self.connect((self.blocks_complex_to_magphase_0_0, 0), (self.qtgui_time_sink_x_0_0, 0))
self.connect((self.blocks_null_source_0, 0), (self.blocks_stream_mux_0, 0))
- self.connect((self.blocks_repack_bits_bb_0, 0), (self.epy_block_1, 0))
+ self.connect((self.blocks_repack_bits_bb_0, 0), (self.blocks_tagged_stream_align_0, 0))
self.connect((self.blocks_stream_mux_0, 0), (self.digital_constellation_modulator_0, 0))
+ self.connect((self.blocks_tagged_stream_align_0, 0), (self.epy_block_1, 0))
self.connect((self.blocks_throttle_0, 0), (self.digital_pfb_clock_sync_xxx_0, 0))
self.connect((self.blocks_vector_source_x_0, 0), (self.blocks_stream_mux_0, 1))
self.connect((self.channels_channel_model_0, 0), (self.blocks_throttle_0, 0))
self.connect((self.digital_cma_equalizer_cc_0, 0), (self.digital_corr_est_cc_0, 0))
self.connect((self.digital_cma_equalizer_cc_0, 0), (self.qtgui_const_sink_x_0, 0))
- self.connect((self.digital_constellation_decoder_cb_0, 0), (self.blocks_repack_bits_bb_0, 0))
+ self.connect((self.digital_constellation_decoder_cb_0, 0), (self.digital_map_bb_0, 0))
self.connect((self.digital_constellation_modulator_0, 0), (self.channels_channel_model_0, 0))
self.connect((self.digital_constellation_modulator_0, 0), (self.qtgui_time_sink_x_1_0, 0))
self.connect((self.digital_corr_est_cc_0, 1), (self.blocks_complex_to_magphase_0_0, 0))
@@ -382,6 +385,7 @@ class correlator(gr.top_block, Qt.QWidget):
self.connect((self.digital_corr_est_cc_0, 0), (self.epy_block_0, 0))
self.connect((self.digital_corr_est_cc_0, 0), (self.qtgui_time_sink_x_0_0_0, 0))
self.connect((self.digital_costas_loop_cc_0, 0), (self.qtgui_const_sink_x_0_0, 1))
+ self.connect((self.digital_map_bb_0, 0), (self.blocks_repack_bits_bb_0, 0))
self.connect((self.digital_pfb_clock_sync_xxx_0, 0), (self.digital_cma_equalizer_cc_0, 0))
self.connect((self.epy_block_0, 0), (self.digital_constellation_decoder_cb_0, 0))
self.connect((self.epy_block_0, 0), (self.qtgui_const_sink_x_0_0, 0))
@@ -463,6 +467,7 @@ class correlator(gr.top_block, Qt.QWidget):
def set_access_code_symbols(self, access_code_symbols):
self.access_code_symbols = access_code_symbols
+ self.digital_corr_est_cc_0.set_mark_delay(len(self.access_code_symbols) // 2)
diff --git a/tests/correlator/epy_block_0.py b/tests/correlator/epy_block_0.py
index ddae02a..dbdadd1 100644
--- a/tests/correlator/epy_block_0.py
+++ b/tests/correlator/epy_block_0.py
@@ -5,6 +5,12 @@ from gnuradio import gr
class blk(gr.sync_block):
+ """
+ Apply phase and frequency correction where there is a correlation peak tag.
+
+ The correlation peak tags are NOT propagated, and instead replaced with a
+ frame_start tag.
+ """
def __init__(self):
gr.sync_block.__init__(
self,
@@ -22,7 +28,17 @@ class blk(gr.sync_block):
self.lastfreq = 0
def block_phase(self, start, end):
- # compute number of samples in block
+ """
+ Compute a vector for the phase and frequency correction for the samples
+ between two tags (start and end).
+
+ @param start Tag where the samples should start to be corrected
+ @param end Tag where to stop correcting
+
+ @return A vector of phase values for each sample. To correct the samples
+ the data should be multiplied with np.exp(-1j * phase)
+ """
+ # compute number of samples between tags
nsamples = end.offset - start.offset
# unpack pmt values into start and end phase
@@ -44,10 +60,10 @@ class blk(gr.sync_block):
self.lastfreq = freq
# debugging
- print(f"Correction for block of {nsamples:2d} samples is " \
+ print(f"Correction for chunk of {nsamples:2d} samples is " \
f"sphase={sphase: .4f} rad and freq={freq*1e3: .4f} milli rad / sample")
- # compute block values
+ # compute chunk values
return sphase * np.ones(nsamples) + freq * np.arange(0, nsamples)
def work(self, input_items, output_items):
@@ -73,11 +89,11 @@ class blk(gr.sync_block):
# compute "the middle"
enough_samples = lambda pair: ((pair[1].offset - pair[0].offset) > 0)
pairs = list(filter(enough_samples, zip(tags, tags[1:])))
- blocks = [ self.block_phase(start, end) for (start, end) in pairs ]
- middle = np.concatenate(blocks) if blocks else []
+ chunks = [ self.block_phase(start, end) for (start, end) in pairs ]
+ middle = np.concatenate(chunks) if chunks else []
# compute values at the end, we do not have informations about the future
- # but we can use the frequency of the last block to approximate
+ # but we can use the frequency of the last tag to approximate
nback = len(inp) - (tags[-1].offset - counter)
print(f"Processing {nback} samples at the back of the buffer")
end = np.ones(nback) * pmt.to_python(tags[-1].value) \
@@ -99,6 +115,10 @@ class blk(gr.sync_block):
# save last tag for next call
self.last = tags[-1]
+ # add tags
+ for tag in tags:
+ self.add_item_tag(0, tag.offset, pmt.intern("frame_start"), pmt.PMT_T)
+
# FIXME: should return `length' but then the last sample is not
# included and self.last does something weird
return len(out)