summaryrefslogtreecommitdiff
path: root/gnuradio-core/src/python
diff options
context:
space:
mode:
authortrondeau2008-04-15 17:12:18 +0000
committertrondeau2008-04-15 17:12:18 +0000
commit42b48770e756f1c082f5dfc9e757fafe69263496 (patch)
tree18820226adff7aca46205d2f7e6dafa5f635c8e7 /gnuradio-core/src/python
parent3a2f0b7e9fedaa29dbce47fe5d0b61ac8135aefb (diff)
downloadgnuradio-42b48770e756f1c082f5dfc9e757fafe69263496.tar.gz
gnuradio-42b48770e756f1c082f5dfc9e757fafe69263496.tar.bz2
gnuradio-42b48770e756f1c082f5dfc9e757fafe69263496.zip
Mostly fixed the van de Beek ML synchronization scheme. Instead of using the CP timing signal, it correlates against the known preamble just to send along the timing trigger. This works nicely and keeps the frequency more constant in the receiver since it updates the estimate every received symbol. Read the comments inside to see why it's 'mostly fixed' -- this was mostly proving a point for myself today.
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@8199 221aa14e-8319-0410-a670-987f0aec2ac5
Diffstat (limited to 'gnuradio-core/src/python')
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_ml.py59
1 files changed, 34 insertions, 25 deletions
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_ml.py b/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_ml.py
index a93852623..59c4913d1 100644
--- a/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_ml.py
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_ml.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2007 Free Software Foundation, Inc.
+# Copyright 2007,2008 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -24,21 +24,16 @@ import math
from gnuradio import gr
class ofdm_sync_ml(gr.hier_block2):
- def __init__(self, fft_length, cp_length, snr, logging):
+ def __init__(self, fft_length, cp_length, snr, kstime, logging):
''' Maximum Likelihood OFDM synchronizer:
J. van de Beek, M. Sandell, and P. O. Borjesson, "ML Estimation
of Time and Frequency Offset in OFDM Systems," IEEE Trans.
Signal Processing, vol. 45, no. 7, pp. 1800-1805, 1997.
'''
- # FIXME: change the output signature
- # should be the output of the divider (the normalized peaks) and
- # the angle value out of the sample and hold block
- # move sampler out of this block
-
gr.hier_block2.__init__(self, "ofdm_sync_ml",
gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
- gr.io_signature(1, 1, gr.sizeof_gr_complex*fft_length)) # Output signature
+ gr.io_signature2(2, 2, gr.sizeof_float, gr.sizeof_char)) # Output signature
self.input = gr.add_const_cc(0)
@@ -92,19 +87,9 @@ class ofdm_sync_ml(gr.hier_block2):
self.connect(self.moving_sum_filter,(self.diff,1))
#ML measurements input to sampler block and detect
- nco_sensitivity = -1.0/fft_length
self.f2c = gr.float_to_complex()
- self.sampler = gr.ofdm_sampler(fft_length,symbol_length)
self.pk_detect = gr.peak_detector_fb(0.2, 0.25, 30, 0.0005)
- #self.pk_detect = gr.peak_detector2_fb()
self.sample_and_hold = gr.sample_and_hold_ff()
- self.nco = gr.frequency_modulator_fc(nco_sensitivity)
- self.sigmix = gr.multiply_cc()
-
- # Mix the signal with an NCO controlled by the sync loop
- self.connect(self.input, (self.sigmix,0))
- self.connect(self.nco, (self.sigmix,1))
- self.connect(self.sigmix, (self.sampler,0))
# use the sync loop values to set the sampler and the NCO
# self.diff = theta
@@ -112,20 +97,47 @@ class ofdm_sync_ml(gr.hier_block2):
self.connect(self.diff, self.pk_detect)
+ # The DPLL corrects for timing differences between CP correlations
use_dpll = 1
if use_dpll:
self.dpll = gr.dpll_bb(float(symbol_length),0.01)
self.connect(self.pk_detect, self.dpll)
- self.connect(self.dpll, (self.sampler,1))
self.connect(self.dpll, (self.sample_and_hold,1))
else:
- self.connect(self.pk_detect, (self.sampler,1))
self.connect(self.pk_detect, (self.sample_and_hold,1))
self.connect(self.angle, (self.sample_and_hold,0))
- self.connect(self.sample_and_hold, self.nco)
- self.connect(self.sampler, self)
+ ################################
+ # correlate against known symbol
+ # This gives us the same timing signal as the PN sync block only on the preamble
+ # we don't use the signal generated from the CP correlation because we don't want
+ # to readjust the timing in the middle of the packet or we ruin the equalizer settings.
+ kstime = [k.conjugate() for k in kstime]
+ kstime.reverse()
+ self.kscorr = gr.fir_filter_ccc(1, kstime)
+ self.corrmag = gr.complex_to_mag_squared()
+
+ # The output signature of the correlation has a few spikes because the rest of the
+ # system uses the repeated preamble symbol. It needs to work that generically if
+ # anyone wants to use this against a WiMAX-like signal since it, too, repeats
+ # This slicing against a threshold will __not__ work over the air unless the
+ # received power is at just the right point. It __does__ work under the normal
+ # conditions of the loopback model.
+ self.slice = gr.threshold_ff(700000, 700000, 0)
+ self.f2b = gr.float_to_char()
+
+ self.connect(self.input, self.kscorr, self.corrmag, self.slice)
+ self.connect(self.kscorr, gr.file_sink(gr.sizeof_gr_complex, "kscorr.dat"))
+ self.connect(self.corrmag, gr.file_sink(gr.sizeof_float, "kscorrmag.dat"))
+ self.connect(self.slice, gr.file_sink(gr.sizeof_float, "kspeak.dat"))
+
+ # Set output signals
+ # Output 0: fine frequency correction value
+ # Output 1: timing signal
+ self.connect(self.sample_and_hold, (self,0))
+ self.connect(self.slice, self.f2b, (self,1))
+
if logging:
self.connect(self.diff, gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-theta_f.dat"))
@@ -134,9 +146,6 @@ class ofdm_sync_ml(gr.hier_block2):
if use_dpll:
self.connect(self.dpll, gr.file_sink(gr.sizeof_char, "ofdm_sync_ml-dpll_b.dat"))
- self.connect(self.sigmix, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_ml-sigmix_c.dat"))
- self.connect(self.sampler, gr.file_sink(gr.sizeof_gr_complex*fft_length, "ofdm_sync_ml-sampler_c.dat"))
self.connect(self.sample_and_hold, gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-sample_and_hold_f.dat"))
- self.connect(self.nco, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_ml-nco_c.dat"))
self.connect(self.input, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_ml-input_c.dat"))