From ae5b4ed2ce8c4a0903eea1b264da5393a179c9fe Mon Sep 17 00:00:00 2001 From: Johnathan Corgan Date: Sat, 31 Oct 2009 09:28:44 -0700 Subject: [PATCH] gr-noaa: Switched to 'double rate BPSK' HRPT synchronization Added hrpt_bit_sync block Using MM clock sync at double data rate Created file_rx_hrpt GRC app Updated demod_rx_hrpt GRC app Updated usrp_rx_hrpt GRC Updated usrp_rx_hrpt_nogui app Deleted usrp_rx_hrpt2 GRC app Deleted hrpt_sync_fb block --- gr-noaa/README | 27 +- gr-noaa/apps/.gitignore | 1 + gr-noaa/apps/Makefile.am | 4 +- gr-noaa/apps/demod_hrpt_file.grc | 491 ++++---- gr-noaa/apps/demod_hrpt_file.py | 110 +- .../{usrp_rx_hrpt2.grc => file_rx_hrpt.grc} | 1044 +++++++---------- gr-noaa/apps/file_rx_hrpt.py | 309 +++++ gr-noaa/apps/usrp_rx_hrpt.cfg | 13 - gr-noaa/apps/usrp_rx_hrpt.grc | 704 +++++------ gr-noaa/apps/usrp_rx_hrpt.py | 289 +++-- gr-noaa/apps/usrp_rx_hrpt2.py | 401 ------- gr-noaa/apps/usrp_rx_hrpt_nogui.grc | 335 ++++-- gr-noaa/apps/usrp_rx_hrpt_nogui.py | 191 ++- gr-noaa/grc/Makefile.am | 4 +- gr-noaa/grc/noaa_hrpt_bit_sync.xml | 16 + gr-noaa/grc/noaa_hrpt_sync_fb.xml | 39 - gr-noaa/lib/Makefile.am | 8 +- gr-noaa/lib/noaa_hrpt_bit_sync.cc | 72 ++ gr-noaa/lib/noaa_hrpt_bit_sync.h | 49 + gr-noaa/lib/noaa_hrpt_sync_fb.cc | 95 -- gr-noaa/lib/noaa_hrpt_sync_fb.h | 58 - gr-noaa/swig/Makefile.am | 4 +- ...aa_hrpt_sync_fb.i => noaa_hrpt_bit_sync.i} | 15 +- gr-noaa/swig/noaa_swig.i | 5 +- 24 files changed, 2043 insertions(+), 2241 deletions(-) rename gr-noaa/apps/{usrp_rx_hrpt2.grc => file_rx_hrpt.grc} (71%) create mode 100755 gr-noaa/apps/file_rx_hrpt.py delete mode 100644 gr-noaa/apps/usrp_rx_hrpt.cfg delete mode 100755 gr-noaa/apps/usrp_rx_hrpt2.py create mode 100644 gr-noaa/grc/noaa_hrpt_bit_sync.xml delete mode 100644 gr-noaa/grc/noaa_hrpt_sync_fb.xml create mode 100644 gr-noaa/lib/noaa_hrpt_bit_sync.cc create mode 100644 gr-noaa/lib/noaa_hrpt_bit_sync.h delete mode 100644 gr-noaa/lib/noaa_hrpt_sync_fb.cc delete mode 100644 gr-noaa/lib/noaa_hrpt_sync_fb.h rename gr-noaa/swig/{noaa_hrpt_sync_fb.i => noaa_hrpt_bit_sync.i} (72%) diff --git a/gr-noaa/README b/gr-noaa/README index fada3550..29d11f59 100644 --- a/gr-noaa/README +++ b/gr-noaa/README @@ -15,20 +15,22 @@ HRPT minor frames into a file. The file stores a series of 11090 word, 16-bits per word corresponding to the HRPT minor frame format (only the lower 10-bits per word are significant.) -The script file by default uses USRP side A, 1698 MHz, at decimation 16. A -configuration file 'usrp_rx_hrpt.cfg' in the current working directory will -allow changing this, as well as implementing persistent storage of GUI +The script file by default uses USRP side A, 1698 MHz, at decimation 16. The +gnuradio configuration file ~/.gnuradio/config.conf, section 'usrp_rx_hrpt.cfg', +will allow changing this, as well as implementing persistent storage of GUI entered parameters from invocation to invocation. The present HRPT demodulator is only tested at decimation 16. The only other -valid decimation rates are 24 and 32, which may word but with more bit +valid decimation rates are 24 and 32, which may work but with more bit errors. No other decimation rates will work. -usrp_rx_hrpt2.py ----------------- -This GUI script uses fewer graphical displays to reduce CPU consumption on -slower machines, but otherwise operates identically to userp_rx_hrpt.py. +file_rx_hrpt.py +--------------- + +This GUI script operates like usrp_rx_hrpt.py, but reads from a pre-captured +data file supplied by -F on the command line. + usrp_rx_hrpt_nogui.py --------------------- @@ -37,6 +39,7 @@ This non-GUI script operates without a display and requires that all parameters be set in the configuration file prior to running. It has no command-line parameters, and works identically to the GUI scripts. + demod_hrpt_file.py ------------------ @@ -53,11 +56,11 @@ Options: Set Decimation [default=16] -p PLL_ALPHA, --pll-alpha=PLL_ALPHA Set pll_alpha [default=50m] - -s SYNC_ALPHA, --sync-alpha=SYNC_ALPHA - Set sync_alpha [default=50m] - -F FILENAME, --filename=FILENAME + -s CLOCK_ALPHA, --clock-alpha=CLOCK_ALPHA + Set clock_alpha [default=50m] + -F INPUT_FILENAME, --input-filename=INPUT_FILENAME Set Filename [default=usrp.dat] - -o OUTPUT, --output=OUTPUT + -o OUTPUT_FILENAME, --output-filename=OUTPUT_FILENAME Set Output [default=frames.dat] diff --git a/gr-noaa/apps/.gitignore b/gr-noaa/apps/.gitignore index 773a6df9..6bd1ab99 100644 --- a/gr-noaa/apps/.gitignore +++ b/gr-noaa/apps/.gitignore @@ -1 +1,2 @@ *.dat +*.txt \ No newline at end of file diff --git a/gr-noaa/apps/Makefile.am b/gr-noaa/apps/Makefile.am index b9787a92..961b09af 100644 --- a/gr-noaa/apps/Makefile.am +++ b/gr-noaa/apps/Makefile.am @@ -25,15 +25,15 @@ if PYTHON dist_bin_SCRIPTS = \ demod_hrpt_file.py \ + file_rx_hrpt.py \ usrp_rx_hrpt.py \ - usrp_rx_hrpt2.py \ usrp_rx_hrpt_nogui.py \ usrp_rx_lrit.py EXTRA_DIST = \ + file_rx_hrpt.grc \ demod_hrpt_file.grc \ usrp_rx_hrpt.grc \ - usrp_rx_hrpt2.grc \ usrp_rx_hrpt_nogui.grc \ usrp_rx_lrit.grc endif diff --git a/gr-noaa/apps/demod_hrpt_file.grc b/gr-noaa/apps/demod_hrpt_file.grc index 7a0bbe89..a5df8786 100644 --- a/gr-noaa/apps/demod_hrpt_file.grc +++ b/gr-noaa/apps/demod_hrpt_file.grc @@ -1,23 +1,55 @@ - Sun Oct 4 08:40:03 2009 + Sun Nov 1 18:39:07 2009 - variable + options id - max_sync_offset + demod_hrpt_file _enabled True - value - 0.01 + title + + + + author + + + + description + + + + window_size + 4096,4096 + + + generate_options + no_gui + + + category + Custom + + + run_options + run + + + run + True + + + realtime_scheduling + _coordinate - (705, 19) + (10, 10) _rotation @@ -51,7 +83,7 @@ variable id - hs + sym_rate _enabled @@ -59,11 +91,11 @@ value - int(sps/2.0) + 600*1109 _coordinate - (499, 19) + (301, 19) _rotation @@ -97,7 +129,7 @@ variable id - sym_rate + hs _enabled @@ -105,11 +137,11 @@ value - 600*1109 + int(sps/2.0) _coordinate - (301, 19) + (499, 19) _rotation @@ -140,34 +172,45 @@ - parameter + variable id - filename + max_clock_offset _enabled True - label - Filename + value + 0.1 - value - usrp.dat + _coordinate + (710, 17) - type - string + _rotation + 0 + + + import - short_id - F + id + import_0 + + + _enabled + True + + + import + import math, os _coordinate - (200, 101) + (11, 103) _rotation @@ -178,7 +221,7 @@ parameter id - output + decim _enabled @@ -186,23 +229,23 @@ label - Output + decim value - frames.dat + 16 type - string + intx short_id - o + d _coordinate - (302, 101) + (202, 102) _rotation @@ -210,45 +253,34 @@ - gr_float_to_complex + parameter id - f2c + pll_alpha _enabled True - vlen - 1 - - - _coordinate - (832, 363) - - - _rotation - 0 + label + pll_alpha - - - virtual_sink - id - samples_sink + value + 0.05 - _enabled - True + type + eng_float - stream_id - samples + short_id + p _coordinate - (1070, 376) + (294, 101) _rotation @@ -256,34 +288,34 @@ - noaa_hrpt_sync_fb + parameter id - sync + clock_alpha _enabled True - alpha - sync_alpha + label + clock_alpha - beta - sync_alpha**2/4.0 + value + 0.05 - sps - sps + type + eng_float - max_offset - max_sync_offset + short_id + a _coordinate - (813, 455) + (395, 101) _rotation @@ -291,49 +323,34 @@ - noaa_hrpt_deframer + parameter id - deframer + sync_alpha _enabled True - _coordinate - (1037, 483) - - - _rotation - 0 - - - - gr_file_sink - - id - file_sink - - - _enabled - True + label + sync_alpha - file - output + value + 0.05 type - short + eng_float - vlen - 1 + short_id + s _coordinate - (1238, 479) + (508, 102) _rotation @@ -341,49 +358,34 @@ - noaa_hrpt_decoder + parameter id - decoder + input_filename _enabled True - _coordinate - (1237, 542) - - - _rotation - 0 - - - - gr_deinterleave - - id - deinterleave + label + input_filename - _enabled - True + value + usrp.dat type - float - - - num_streams - 2 + string - vlen - 1 + short_id + F _coordinate - (628, 363) + (618, 102) _rotation @@ -394,7 +396,7 @@ parameter id - decim + output_filename _enabled @@ -402,58 +404,58 @@ label - Decimation + output_filename value - 16 + frames.dat type - intx + string short_id - d + o _coordinate - (415, 101) + (726, 102) _rotation - 0 + 180 - parameter + gr_file_source id - pll_alpha + file_source _enabled True - label - + file + input_filename - value - 0.05 + type + short - type - eng_float + repeat + False - short_id - p + vlen + 1 _coordinate - (527, 101) + (62, 306) _rotation @@ -461,34 +463,57 @@ - parameter + gr_interleaved_short_to_complex id - sync_alpha + cs2cf _enabled True - label - + _coordinate + (297, 318) - value - 0.05 + _rotation + 0 + + + + gr_agc_xx + + id + agc + + + _enabled + True type - eng_float + complex - short_id - s + rate + 1e-5 + + + reference + 1.0 + + + gain + 1.0/32768.0 + + + max_gain + 1.0 _coordinate - (615, 99) + (538, 290) _rotation @@ -519,7 +544,7 @@ _coordinate - (606, 463) + (720, 297) _rotation @@ -527,41 +552,34 @@ - virtual_source + gr_moving_average_xx id - samples_source + gr_moving_average_xx_0 _enabled True - stream_id - samples - - - _coordinate - (164, 479) + type + float - _rotation - 0 + length + hs - - - gr_short_to_float - id - s2f + scale + 1.0/hs - _enabled - True + max_iter + 4000 _coordinate - (365, 380) + (949, 297) _rotation @@ -569,34 +587,42 @@ - gr_file_source + gr_clock_recovery_mm_xx id - file_source + gr_clock_recovery_mm_xx_0 _enabled True - file - filename + type + float - type - short + omega + sps/2.0 - repeat - False + gain_omega + clock_alpha**2/4.0 - vlen - 1 + mu + 0.5 + + + gain_mu + clock_alpha + + + omega_relative_limit + max_clock_offset _coordinate - (162, 368) + (1158, 281) _rotation @@ -604,22 +630,18 @@ - variable + gr_binary_slicer_fb id - mf_taps + gr_binary_slicer_fb_0 _enabled True - - value - [-0.5/hs,]*hs+[0.5/hs,]*hs - _coordinate - (829, 21) + (112, 537) _rotation @@ -627,30 +649,30 @@ - gr_fir_filter_xxx + gr_file_sink id - gr_fir_filter_xxx_0 + gr_file_sink_0 _enabled True - type - ccc + file + output_filename - decim - 1 + type + short - taps - mf_taps + vlen + 1 _coordinate - (359, 471) + (732, 615) _rotation @@ -658,22 +680,18 @@ - import + noaa_hrpt_decoder id - import_0 + noaa_hrpt_decoder_0 _enabled True - - import - import math - _coordinate - (11, 111) + (730, 537) _rotation @@ -681,54 +699,37 @@ - options + noaa_hrpt_bit_sync id - demod_hrpt_file + noaa_hrpt_bit_sync_0 _enabled True - title - USRP HRPT Receiver - - - author - - - - description - - - - window_size - 4096,4096 - - - generate_options - no_gui + _coordinate + (330, 537) - category - Custom + _rotation + 0 + + + noaa_hrpt_deframer - run_options - run + id + noaa_hrpt_deframer_0 - run + _enabled True - - realtime_scheduling - - _coordinate - (10, 10) + (536, 537) _rotation @@ -736,68 +737,62 @@ - deframer - file_sink + file_source + cs2cf 0 0 - sync - deframer + gr_clock_recovery_mm_xx_0 + gr_binary_slicer_fb_0 0 0 - pll - sync + gr_moving_average_xx_0 + gr_clock_recovery_mm_xx_0 0 0 - deinterleave - f2c - 1 - 1 - - - deinterleave - f2c + pll + gr_moving_average_xx_0 0 0 - deframer - decoder + gr_binary_slicer_fb_0 + noaa_hrpt_bit_sync_0 0 0 - f2c - samples_sink + cs2cf + agc 0 0 - gr_fir_filter_xxx_0 + agc pll 0 0 - samples_source - gr_fir_filter_xxx_0 + noaa_hrpt_deframer_0 + gr_file_sink_0 0 0 - s2f - deinterleave + noaa_hrpt_deframer_0 + noaa_hrpt_decoder_0 0 0 - file_source - s2f + noaa_hrpt_bit_sync_0 + noaa_hrpt_deframer_0 0 0 diff --git a/gr-noaa/apps/demod_hrpt_file.py b/gr-noaa/apps/demod_hrpt_file.py index d5535186..84672318 100755 --- a/gr-noaa/apps/demod_hrpt_file.py +++ b/gr-noaa/apps/demod_hrpt_file.py @@ -1,8 +1,8 @@ #!/usr/bin/env python ################################################## # Gnuradio Python Flow Graph -# Title: USRP HRPT Receiver -# Generated: Sun Oct 4 08:40:03 2009 +# Title: Demod Hrpt File +# Generated: Sun Nov 1 18:39:07 2009 ################################################## from gnuradio import eng_notation @@ -11,21 +11,22 @@ from gnuradio import noaa from gnuradio.eng_option import eng_option from gnuradio.gr import firdes from optparse import OptionParser -import math +import math, os class demod_hrpt_file(gr.top_block): - def __init__(self, filename="usrp.dat", output="frames.dat", decim=16, pll_alpha=0.05, sync_alpha=0.05): - gr.top_block.__init__(self, "USRP HRPT Receiver") + def __init__(self, decim=16, pll_alpha=0.05, clock_alpha=0.05, sync_alpha=0.05, input_filename="usrp.dat", output_filename="frames.dat"): + gr.top_block.__init__(self, "Demod Hrpt File") ################################################## # Parameters ################################################## - self.filename = filename - self.output = output self.decim = decim self.pll_alpha = pll_alpha + self.clock_alpha = clock_alpha self.sync_alpha = sync_alpha + self.input_filename = input_filename + self.output_filename = output_filename ################################################## # Variables @@ -33,44 +34,38 @@ class demod_hrpt_file(gr.top_block): self.sym_rate = sym_rate = 600*1109 self.sample_rate = sample_rate = 64e6/decim self.sps = sps = sample_rate/sym_rate - self.hs = hs = int(sps/2.0) - self.mf_taps = mf_taps = [-0.5/hs,]*hs+[0.5/hs,]*hs - self.max_sync_offset = max_sync_offset = 0.01 + self.max_clock_offset = max_clock_offset = 0.1 self.max_carrier_offset = max_carrier_offset = 2*math.pi*100e3/sample_rate + self.hs = hs = int(sps/2.0) ################################################## # Blocks ################################################## - self.decoder = noaa.hrpt_decoder() - self.deframer = noaa.hrpt_deframer() - self.deinterleave = gr.deinterleave(gr.sizeof_float*1) - self.f2c = gr.float_to_complex(1) - self.file_sink = gr.file_sink(gr.sizeof_short*1, output) - self.file_source = gr.file_source(gr.sizeof_short*1, filename, False) - self.gr_fir_filter_xxx_0 = gr.fir_filter_ccc(1, (mf_taps)) + self.agc = gr.agc_cc(1e-5, 1.0, 1.0/32768.0, 1.0) + self.cs2cf = gr.interleaved_short_to_complex() + self.file_source = gr.file_source(gr.sizeof_short*1, input_filename, False) + self.gr_binary_slicer_fb_0 = gr.binary_slicer_fb() + self.gr_clock_recovery_mm_xx_0 = gr.clock_recovery_mm_ff(sps/2.0, clock_alpha**2/4.0, 0.5, clock_alpha, max_clock_offset) + self.gr_file_sink_0 = gr.file_sink(gr.sizeof_short*1, output_filename) + self.gr_moving_average_xx_0 = gr.moving_average_ff(hs, 1.0/hs, 4000) + self.noaa_hrpt_bit_sync_0 = noaa.hrpt_bit_sync() + self.noaa_hrpt_decoder_0 = noaa.hrpt_decoder() + self.noaa_hrpt_deframer_0 = noaa.hrpt_deframer() self.pll = noaa.hrpt_pll_cf(pll_alpha, pll_alpha**2/4.0, max_carrier_offset) - self.s2f = gr.short_to_float() - self.sync = noaa.hrpt_sync_fb(sync_alpha, sync_alpha**2/4.0, sps, max_sync_offset) ################################################## # Connections ################################################## - self.connect((self.deframer, 0), (self.file_sink, 0)) - self.connect((self.sync, 0), (self.deframer, 0)) - self.connect((self.pll, 0), (self.sync, 0)) - self.connect((self.deinterleave, 1), (self.f2c, 1)) - self.connect((self.deinterleave, 0), (self.f2c, 0)) - self.connect((self.deframer, 0), (self.decoder, 0)) - self.connect((self.gr_fir_filter_xxx_0, 0), (self.pll, 0)) - self.connect((self.f2c, 0), (self.gr_fir_filter_xxx_0, 0)) - self.connect((self.s2f, 0), (self.deinterleave, 0)) - self.connect((self.file_source, 0), (self.s2f, 0)) - - def set_filename(self, filename): - self.filename = filename - - def set_output(self, output): - self.output = output + self.connect((self.file_source, 0), (self.cs2cf, 0)) + self.connect((self.gr_clock_recovery_mm_xx_0, 0), (self.gr_binary_slicer_fb_0, 0)) + self.connect((self.gr_moving_average_xx_0, 0), (self.gr_clock_recovery_mm_xx_0, 0)) + self.connect((self.pll, 0), (self.gr_moving_average_xx_0, 0)) + self.connect((self.gr_binary_slicer_fb_0, 0), (self.noaa_hrpt_bit_sync_0, 0)) + self.connect((self.cs2cf, 0), (self.agc, 0)) + self.connect((self.agc, 0), (self.pll, 0)) + self.connect((self.noaa_hrpt_deframer_0, 0), (self.gr_file_sink_0, 0)) + self.connect((self.noaa_hrpt_deframer_0, 0), (self.noaa_hrpt_decoder_0, 0)) + self.connect((self.noaa_hrpt_bit_sync_0, 0), (self.noaa_hrpt_deframer_0, 0)) def set_decim(self, decim): self.decim = decim @@ -81,10 +76,19 @@ class demod_hrpt_file(gr.top_block): self.pll.set_alpha(self.pll_alpha) self.pll.set_beta(self.pll_alpha**2/4.0) + def set_clock_alpha(self, clock_alpha): + self.clock_alpha = clock_alpha + self.gr_clock_recovery_mm_xx_0.set_gain_omega(self.clock_alpha**2/4.0) + self.gr_clock_recovery_mm_xx_0.set_gain_mu(self.clock_alpha) + def set_sync_alpha(self, sync_alpha): self.sync_alpha = sync_alpha - self.sync.set_alpha(self.sync_alpha) - self.sync.set_beta(self.sync_alpha**2/4.0) + + def set_input_filename(self, input_filename): + self.input_filename = input_filename + + def set_output_filename(self, output_filename): + self.output_filename = output_filename def set_sym_rate(self, sym_rate): self.sym_rate = sym_rate @@ -98,36 +102,34 @@ class demod_hrpt_file(gr.top_block): def set_sps(self, sps): self.sps = sps self.set_hs(int(self.sps/2.0)) + self.gr_clock_recovery_mm_xx_0.set_omega(self.sps/2.0) - def set_hs(self, hs): - self.hs = hs - self.set_mf_taps([-0.5/self.hs,]*self.hs+[0.5/self.hs,]*self.hs) - - def set_mf_taps(self, mf_taps): - self.mf_taps = mf_taps - self.gr_fir_filter_xxx_0.set_taps((self.mf_taps)) - - def set_max_sync_offset(self, max_sync_offset): - self.max_sync_offset = max_sync_offset - self.sync.set_max_offset(self.max_sync_offset) + def set_max_clock_offset(self, max_clock_offset): + self.max_clock_offset = max_clock_offset def set_max_carrier_offset(self, max_carrier_offset): self.max_carrier_offset = max_carrier_offset self.pll.set_max_offset(self.max_carrier_offset) + def set_hs(self, hs): + self.hs = hs + self.gr_moving_average_xx_0.set_length_and_scale(self.hs, 1.0/self.hs) + if __name__ == '__main__': parser = OptionParser(option_class=eng_option, usage="%prog: [options]") - parser.add_option("-F", "--filename", dest="filename", type="string", default="usrp.dat", - help="Set Filename [default=%default]") - parser.add_option("-o", "--output", dest="output", type="string", default="frames.dat", - help="Set Output [default=%default]") parser.add_option("-d", "--decim", dest="decim", type="intx", default=16, - help="Set Decimation [default=%default]") + help="Set decim [default=%default]") parser.add_option("-p", "--pll-alpha", dest="pll_alpha", type="eng_float", default=eng_notation.num_to_str(0.05), help="Set pll_alpha [default=%default]") + parser.add_option("-a", "--clock-alpha", dest="clock_alpha", type="eng_float", default=eng_notation.num_to_str(0.05), + help="Set clock_alpha [default=%default]") parser.add_option("-s", "--sync-alpha", dest="sync_alpha", type="eng_float", default=eng_notation.num_to_str(0.05), help="Set sync_alpha [default=%default]") + parser.add_option("-F", "--input-filename", dest="input_filename", type="string", default="usrp.dat", + help="Set usrp.dat [default=%default]") + parser.add_option("-o", "--output-filename", dest="output_filename", type="string", default="frames.dat", + help="Set frames.dat [default=%default]") (options, args) = parser.parse_args() - tb = demod_hrpt_file(filename=options.filename, output=options.output, decim=options.decim, pll_alpha=options.pll_alpha, sync_alpha=options.sync_alpha) + tb = demod_hrpt_file(decim=options.decim, pll_alpha=options.pll_alpha, clock_alpha=options.clock_alpha, sync_alpha=options.sync_alpha, input_filename=options.input_filename, output_filename=options.output_filename) tb.run() diff --git a/gr-noaa/apps/usrp_rx_hrpt2.grc b/gr-noaa/apps/file_rx_hrpt.grc similarity index 71% rename from gr-noaa/apps/usrp_rx_hrpt2.grc rename to gr-noaa/apps/file_rx_hrpt.grc index d42a9eab..fea53f80 100644 --- a/gr-noaa/apps/usrp_rx_hrpt2.grc +++ b/gr-noaa/apps/file_rx_hrpt.grc @@ -1,6 +1,61 @@ - Sun Sep 27 13:32:47 2009 + Sun Nov 1 19:26:11 2009 + + options + + id + file_rx_hrpt + + + _enabled + True + + + title + USRP HRPT Receiver + + + author + + + + description + + + + window_size + 4096,4096 + + + generate_options + wx_gui + + + category + Custom + + + run_options + run + + + run + True + + + realtime_scheduling + + + + _coordinate + (10, 10) + + + _rotation + 0 + + variable @@ -117,54 +172,65 @@ - variable_slider + variable id - gain + max_clock_offset _enabled True - label - RX Gain + value + 0.1 - value - saved_gain + _coordinate + (705, 19) - min + _rotation 0 + + + variable_config + + id + side + - max - 100 + _enabled + True - num_steps - 100 + value + 'A' - style - wx.SL_HORIZONTAL + type + string - converver - float_converter + config_file + config_filename - grid_pos - 0, 1, 1, 1 + section + 'usrp_rx_hrpt' - notebook - + option + 'side' + + + writeback + side _coordinate - (340, 106) + (194, 253) _rotation @@ -172,42 +238,49 @@ - variable_text_box + noaa_hrpt_deframer id - freq + deframer _enabled True - label - Frequency + _coordinate + (762, 975) - value - saved_freq + _rotation + 0 + + + gr_file_sink - converver - float_converter + id + frame_sink - formatter - None + _enabled + True - grid_pos - 0, 0, 1, 1 + file + output_filename - notebook - + type + short + + + vlen + 1 _coordinate - (199, 106) + (973, 1024) _rotation @@ -215,54 +288,60 @@ - variable_slider + noaa_hrpt_bit_sync id - pll_alpha + noaa_hrpt_bit_sync_0 _enabled True - label - PLL Alpha + _coordinate + (571, 975) - value - saved_pll_alpha + _rotation + 0 + + + gr_binary_slicer_fb - min - 0.0 + id + gr_binary_slicer_fb_0 - max - 0.5 + _enabled + True - num_steps - 100 + _coordinate + (393, 975) - style - wx.SL_HORIZONTAL + _rotation + 0 + + + virtual_source - converver - float_converter + id + virtual_source_0 - grid_pos - 0, 2, 1, 1 + _enabled + True - notebook - + stream_id + baseband _coordinate - (479, 106) + (173, 971) _rotation @@ -270,97 +349,109 @@ - variable_slider + wxgui_scopesink2 id - sync_alpha + demod_scope _enabled True - label - SYNC Alpha + type + float - value - saved_sync_alpha + title + Post-Demod - min - 0.0 + samp_rate + sym_rate*2.0 - max + v_scale 0.5 - num_steps - 100 + v_offset + 0 - style - wx.SL_HORIZONTAL + t_scale + 10.0/sym_rate - converver - float_converter + ac_couple + False + + + xy_mode + False + + + num_inputs + 1 + + + win_size + grid_pos - 0, 3, 1, 1 + 0, 0, 1, 1 notebook - + displays, 1 _coordinate - (618, 106) + (666, 542) _rotation - 0 + 180 - variable_static_text + gr_clock_recovery_mm_xx id - side_text + gr_clock_recovery_mm_xx_0 _enabled True - label - USRP Side + type + float - value - side + omega + sps/2.0 - converver - str_converter + gain_omega + clock_alpha**2/4.0 - formatter - None + mu + 0.5 - grid_pos - 1, 0, 1, 1 + gain_mu + clock_alpha - notebook - + omega_relative_limit + max_clock_offset _coordinate - (828, 20) + (873, 696) _rotation @@ -368,42 +459,34 @@ - variable_config + gr_moving_average_xx id - side + gr_moving_average_xx_0 _enabled True - - value - 'A' - type - string - - - config_file - config_filename + float - section - 'usrp' + length + hs - option - 'side' + scale + 1.0/hs - writeback - side + max_iter + 4000 _coordinate - (194, 253) + (682, 713) _rotation @@ -411,42 +494,30 @@ - variable_config + noaa_hrpt_pll_cf id - decim + pll _enabled True - value - 16 - - - type - real - - - config_file - config_filename - - - section - 'usrp' + alpha + pll_alpha - option - 'decim' + beta + pll_alpha**2/4.0 - writeback - decim + max_offset + max_carrier_offset _coordinate - (351, 255) + (469, 713) _rotation @@ -454,42 +525,22 @@ - variable_config + virtual_sink id - saved_freq + virtual_sink_0 _enabled True - value - 1698e6 - - - type - real - - - config_file - config_filename - - - section - 'usrp' - - - option - 'freq' - - - writeback - freq + stream_id + baseband _coordinate - (507, 258) + (1142, 728) _rotation @@ -497,42 +548,18 @@ - variable_config + noaa_hrpt_decoder id - saved_gain + decoder _enabled True - - value - 35 - - - type - real - - - config_file - config_filename - - - section - 'usrp' - - - option - 'gain' - - - writeback - gain - _coordinate - (664, 259) + (974, 925) _rotation @@ -540,10 +567,10 @@ - variable_config + variable id - saved_pll_alpha + config_filename _enabled @@ -551,31 +578,11 @@ value - 0.05 - - - type - real - - - config_file - config_filename - - - section - 'demod' - - - option - 'pll_alpha' - - - writeback - pll_alpha + os.environ['HOME']+'/.gnuradio/config.conf' _coordinate - (823, 258) + (13, 159) _rotation @@ -583,42 +590,22 @@ - variable_config + import id - saved_sync_alpha + import_0 _enabled True - value - 0.05 - - - type - real - - - config_file - config_filename - - - section - 'demod' - - - option - 'sync_alpha' - - - writeback - sync_alpha + import + import math, os _coordinate - (981, 258) + (11, 110) _rotation @@ -626,42 +613,38 @@ - variable_config + gr_agc_xx id - output_filename + agc _enabled True - - value - 'frames.dat' - type - string + complex - config_file - config_filename + rate + 1e-6 - section - 'output' + reference + 1.0 - option - 'filename' + gain + 1.0 - writeback - output_filename + max_gain + 1.0 _coordinate - (1139, 259) + (301, 705) _rotation @@ -669,42 +652,18 @@ - variable_static_text + gr_interleaved_short_to_complex id - decim_text + gr_interleaved_short_to_complex_0 _enabled True - - label - Decimation - - - value - decim - - - converver - float_converter - - - formatter - None - - - grid_pos - 1, 1, 1, 1 - - - notebook - - _coordinate - (973, 20) + (73, 733) _rotation @@ -712,68 +671,65 @@ - variable + gr_throttle id - max_sync_offset + throttle _enabled True - value - 0.01 + type + short + + + samples_per_second + sample_rate + + + vlen + 1 _coordinate - (705, 19) + (75, 679) _rotation - 0 + 180 - variable + gr_file_source id - config_filename + gr_file_source_0 _enabled True - value - 'usrp_rx_hrpt.cfg' - - - _coordinate - (12, 160) - - - _rotation - 0 + file + input_filename - - - import - id - import_0 + type + short - _enabled - True + repeat + False - import - import math + vlen + 1 _coordinate - (11, 102) + (76, 613) _rotation @@ -781,30 +737,34 @@ - noaa_hrpt_pll_cf + parameter id - pll + input_filename _enabled True - alpha - pll_alpha + label + input_filename - beta - pll_alpha**2/4.0 + value + 'usrp.dat' - max_offset - max_carrier_offset + type + string + + + short_id + F _coordinate - (664, 809) + (198, 107) _rotation @@ -812,34 +772,34 @@ - noaa_hrpt_sync_fb + parameter id - sync + decim _enabled True - alpha - sync_alpha + label + decim - beta - sync_alpha**2/4.0 + value + 16 - sps - sps + type + intx - max_offset - max_sync_offset + short_id + d _coordinate - (865, 801) + (308, 107) _rotation @@ -847,68 +807,54 @@ - gr_file_sink + variable_slider id - frame_sink + pll_alpha _enabled True - file - output_filename - - - type - short - - - vlen - 1 + label + PLL Alpha - _coordinate - (1283, 937) + value + saved_pll_alpha - _rotation - 0 + min + 0.0 - - - noaa_hrpt_deframer - id - deframer + max + 0.5 - _enabled - True + num_steps + 100 - _coordinate - (1091, 829) + style + wx.SL_HORIZONTAL - _rotation - 0 + converver + float_converter - - - noaa_hrpt_decoder - id - decoder + grid_pos + 0, 0, 1, 1 - _enabled - True + notebook + _coordinate - (1281, 829) + (397, 108) _rotation @@ -916,50 +862,46 @@ - wxgui_scopesink2 + variable_slider id - pll_scope + clock_alpha _enabled True - type - float + label + Clock Alpha - title - Demod Waveform + value + saved_clock_alpha - samp_rate - sample_rate + min + 0.0 - v_scale + max 0.5 - t_scale - 20.0/sample_rate - - - ac_couple - False + num_steps + 100 - xy_mode - False + style + wx.SL_HORIZONTAL - num_inputs - 1 + converver + float_converter grid_pos - 2,0,1,4 + 0, 1, 1, 1 notebook @@ -967,77 +909,50 @@ _coordinate - (631, 632) + (539, 105) _rotation - 180 + 0 - gr_agc_xx + variable_config id - agc + saved_pll_alpha _enabled True - type - complex - - - rate - 1e-6 - - - reference - 1.0 - - - gain - 1.0 - - - max_gain - 1.0 - - - _coordinate - (269, 801) - - - _rotation - 0 + value + 0.05 - - - gr_fir_filter_xxx - id - gr_fir_filter_xxx_0 + type + real - _enabled - True + config_file + config_filename - type - ccc + section + 'usrp_rx_hrpt' - decim - 1 + option + 'pll_alpha' - taps - mf_taps + writeback + pll_alpha _coordinate - (418, 817) + (363, 254) _rotation @@ -1045,10 +960,10 @@ - variable + variable_config id - mf_taps + saved_clock_alpha _enabled @@ -1056,46 +971,31 @@ value - [-0.5/hs,]*hs+[0.5/hs,]*hs - - - _coordinate - (830, 154) - - - _rotation - 0 - - - - gr_file_source - - id - file_source + 0.05 - _enabled - False + type + real - file - 'usrp.dat' + config_file + config_filename - type - short + section + 'usrp_rx_hrpt' - repeat - False + option + 'clock_alpha' - vlen - 1 + writeback + clock_alpha _coordinate - (215, 490) + (527, 256) _rotation @@ -1103,53 +1003,42 @@ - gr_deinterleave + variable_config id - gr_deinterleave_0 + output_filename _enabled - False - - - type - float - - - num_streams - 2 + True - vlen - 1 + value + 'frames.dat' - _coordinate - (598, 485) + type + string - _rotation - 0 + config_file + config_filename - - - gr_float_to_complex - id - gr_float_to_complex_0 + section + 'usrp_rx_hrpt' - _enabled - False + option + 'filename' - vlen - 1 + writeback + output_filename _coordinate - (801, 485) + (689, 257) _rotation @@ -1157,41 +1046,34 @@ - gr_short_to_float + notebook id - s2f + displays _enabled - False - - - _coordinate - (393, 502) + True - _rotation - 0 + style + wx.NB_TOP - - - virtual_sink - id - sample_stream + labels + ['Spectrum','Demod'] - _enabled - False + grid_pos + 1,0,1,2 - stream_id - samples + notebook + _coordinate - (1027, 498) + (12, 249) _rotation @@ -1199,10 +1081,10 @@ - usrp_simple_source_x + wxgui_fftsink2 id - usrp_source + rx_fft _enabled @@ -1213,118 +1095,72 @@ complex - format - - - - which - 0 - - - decimation - decim - - - frequency - freq + title + RX Spectrum - lo_offset - float('inf') + samp_rate + sample_rate - gain - gain + baseband_freq + 0 - side - side + y_per_div + 5 - rx_ant - RXA + y_divs + 8 - hb_filters - + ref_level + -5 - _coordinate - (63, 785) + ref_scale + 2.0 - _rotation - 0 + fft_size + 1024 - - - virtual_source - id - virtual_source_0 + fft_rate + 15 - _enabled + peak_hold False - stream_id - samples - - - _coordinate - (69, 671) - - - _rotation - 0 - - - - options - - id - usrp_rx_hrpt2 - - - _enabled + average True - title - USRP HRPT Receiver - - - author - - - - description - - - - window_size - 4096,4096 + avg_alpha + 0.1 - generate_options - wx_gui + win + None - category - Custom + win_size + 640, 360 - run - True + grid_pos + 0, 0, 1, 1 - realtime_scheduling - 1 + notebook + displays, 0 _coordinate - (10, 10) + (471, 450) _rotation @@ -1332,86 +1168,86 @@ - gr_fir_filter_xxx_0 - pll + noaa_hrpt_bit_sync_0 + deframer 0 0 - agc - gr_fir_filter_xxx_0 + gr_binary_slicer_fb_0 + noaa_hrpt_bit_sync_0 0 0 - usrp_source - agc + virtual_source_0 + gr_binary_slicer_fb_0 0 0 deframer - decoder + frame_sink 0 0 - pll - pll_scope + deframer + decoder 0 0 - pll - sync + gr_clock_recovery_mm_xx_0 + virtual_sink_0 0 0 - sync - deframer + gr_clock_recovery_mm_xx_0 + demod_scope 0 0 - deframer - frame_sink + gr_moving_average_xx_0 + gr_clock_recovery_mm_xx_0 0 0 - virtual_source_0 - agc + pll + gr_moving_average_xx_0 0 0 - file_source - s2f + agc + pll 0 0 - s2f - gr_deinterleave_0 + agc + rx_fft 0 0 - gr_deinterleave_0 - gr_float_to_complex_0 + gr_interleaved_short_to_complex_0 + agc 0 0 - gr_deinterleave_0 - gr_float_to_complex_0 - 1 - 1 + throttle + gr_interleaved_short_to_complex_0 + 0 + 0 - gr_float_to_complex_0 - sample_stream + gr_file_source_0 + throttle 0 0 diff --git a/gr-noaa/apps/file_rx_hrpt.py b/gr-noaa/apps/file_rx_hrpt.py new file mode 100755 index 00000000..c1491ca0 --- /dev/null +++ b/gr-noaa/apps/file_rx_hrpt.py @@ -0,0 +1,309 @@ +#!/usr/bin/env python +################################################## +# Gnuradio Python Flow Graph +# Title: USRP HRPT Receiver +# Generated: Sun Nov 1 19:26:11 2009 +################################################## + +from gnuradio import eng_notation +from gnuradio import gr +from gnuradio import noaa +from gnuradio import window +from gnuradio.eng_option import eng_option +from gnuradio.gr import firdes +from gnuradio.wxgui import fftsink2 +from gnuradio.wxgui import forms +from gnuradio.wxgui import scopesink2 +from grc_gnuradio import wxgui as grc_wxgui +from optparse import OptionParser +import ConfigParser +import math, os +import wx + +class file_rx_hrpt(grc_wxgui.top_block_gui): + + def __init__(self, input_filename='usrp.dat', decim=16): + grc_wxgui.top_block_gui.__init__(self, title="USRP HRPT Receiver") + + ################################################## + # Parameters + ################################################## + self.input_filename = input_filename + self.decim = decim + + ################################################## + # Variables + ################################################## + self.sym_rate = sym_rate = 600*1109 + self.sample_rate = sample_rate = 64e6/decim + self.config_filename = config_filename = os.environ['HOME']+'/.gnuradio/config.conf' + self.sps = sps = sample_rate/sym_rate + self._saved_pll_alpha_config = ConfigParser.ConfigParser() + self._saved_pll_alpha_config.read(config_filename) + try: saved_pll_alpha = self._saved_pll_alpha_config.getfloat('usrp_rx_hrpt', 'pll_alpha') + except: saved_pll_alpha = 0.05 + self.saved_pll_alpha = saved_pll_alpha + self._saved_clock_alpha_config = ConfigParser.ConfigParser() + self._saved_clock_alpha_config.read(config_filename) + try: saved_clock_alpha = self._saved_clock_alpha_config.getfloat('usrp_rx_hrpt', 'clock_alpha') + except: saved_clock_alpha = 0.05 + self.saved_clock_alpha = saved_clock_alpha + self._side_config = ConfigParser.ConfigParser() + self._side_config.read(config_filename) + try: side = self._side_config.get('usrp_rx_hrpt', 'side') + except: side = 'A' + self.side = side + self.pll_alpha = pll_alpha = saved_pll_alpha + self._output_filename_config = ConfigParser.ConfigParser() + self._output_filename_config.read(config_filename) + try: output_filename = self._output_filename_config.get('usrp_rx_hrpt', 'filename') + except: output_filename = 'frames.dat' + self.output_filename = output_filename + self.max_clock_offset = max_clock_offset = 0.1 + self.max_carrier_offset = max_carrier_offset = 2*math.pi*100e3/sample_rate + self.hs = hs = int(sps/2.0) + self.clock_alpha = clock_alpha = saved_clock_alpha + + ################################################## + # Notebooks + ################################################## + self.displays = wx.Notebook(self.GetWin(), style=wx.NB_TOP) + self.displays.AddPage(grc_wxgui.Panel(self.displays), "Spectrum") + self.displays.AddPage(grc_wxgui.Panel(self.displays), "Demod") + self.GridAdd(self.displays, 1, 0, 1, 2) + + ################################################## + # Controls + ################################################## + _pll_alpha_sizer = wx.BoxSizer(wx.VERTICAL) + self._pll_alpha_text_box = forms.text_box( + parent=self.GetWin(), + sizer=_pll_alpha_sizer, + value=self.pll_alpha, + callback=self.set_pll_alpha, + label="PLL Alpha", + converter=forms.float_converter(), + proportion=0, + ) + self._pll_alpha_slider = forms.slider( + parent=self.GetWin(), + sizer=_pll_alpha_sizer, + value=self.pll_alpha, + callback=self.set_pll_alpha, + minimum=0.0, + maximum=0.5, + num_steps=100, + style=wx.SL_HORIZONTAL, + cast=float, + proportion=1, + ) + self.GridAdd(_pll_alpha_sizer, 0, 0, 1, 1) + _clock_alpha_sizer = wx.BoxSizer(wx.VERTICAL) + self._clock_alpha_text_box = forms.text_box( + parent=self.GetWin(), + sizer=_clock_alpha_sizer, + value=self.clock_alpha, + callback=self.set_clock_alpha, + label="Clock Alpha", + converter=forms.float_converter(), + proportion=0, + ) + self._clock_alpha_slider = forms.slider( + parent=self.GetWin(), + sizer=_clock_alpha_sizer, + value=self.clock_alpha, + callback=self.set_clock_alpha, + minimum=0.0, + maximum=0.5, + num_steps=100, + style=wx.SL_HORIZONTAL, + cast=float, + proportion=1, + ) + self.GridAdd(_clock_alpha_sizer, 0, 1, 1, 1) + + ################################################## + # Blocks + ################################################## + self.agc = gr.agc_cc(1e-6, 1.0, 1.0, 1.0) + self.decoder = noaa.hrpt_decoder() + self.deframer = noaa.hrpt_deframer() + self.demod_scope = scopesink2.scope_sink_f( + self.displays.GetPage(1).GetWin(), + title="Post-Demod", + sample_rate=sym_rate*2.0, + v_scale=0.5, + v_offset=0, + t_scale=10.0/sym_rate, + ac_couple=False, + xy_mode=False, + num_inputs=1, + ) + self.displays.GetPage(1).GridAdd(self.demod_scope.win, 0, 0, 1, 1) + self.frame_sink = gr.file_sink(gr.sizeof_short*1, output_filename) + self.gr_binary_slicer_fb_0 = gr.binary_slicer_fb() + self.gr_clock_recovery_mm_xx_0 = gr.clock_recovery_mm_ff(sps/2.0, clock_alpha**2/4.0, 0.5, clock_alpha, max_clock_offset) + self.gr_file_source_0 = gr.file_source(gr.sizeof_short*1, input_filename, False) + self.gr_interleaved_short_to_complex_0 = gr.interleaved_short_to_complex() + self.gr_moving_average_xx_0 = gr.moving_average_ff(hs, 1.0/hs, 4000) + self.noaa_hrpt_bit_sync_0 = noaa.hrpt_bit_sync() + self.pll = noaa.hrpt_pll_cf(pll_alpha, pll_alpha**2/4.0, max_carrier_offset) + self.rx_fft = fftsink2.fft_sink_c( + self.displays.GetPage(0).GetWin(), + baseband_freq=0, + y_per_div=5, + y_divs=8, + ref_level=-5, + ref_scale=2.0, + sample_rate=sample_rate, + fft_size=1024, + fft_rate=15, + average=True, + avg_alpha=0.1, + title="RX Spectrum", + peak_hold=False, + size=(640, 360), + ) + self.displays.GetPage(0).GridAdd(self.rx_fft.win, 0, 0, 1, 1) + self.throttle = gr.throttle(gr.sizeof_short*1, sample_rate) + + ################################################## + # Connections + ################################################## + self.connect((self.noaa_hrpt_bit_sync_0, 0), (self.deframer, 0)) + self.connect((self.gr_binary_slicer_fb_0, 0), (self.noaa_hrpt_bit_sync_0, 0)) + self.connect((self.gr_clock_recovery_mm_xx_0, 0), (self.gr_binary_slicer_fb_0, 0)) + self.connect((self.deframer, 0), (self.frame_sink, 0)) + self.connect((self.deframer, 0), (self.decoder, 0)) + self.connect((self.gr_clock_recovery_mm_xx_0, 0), (self.demod_scope, 0)) + self.connect((self.gr_moving_average_xx_0, 0), (self.gr_clock_recovery_mm_xx_0, 0)) + self.connect((self.pll, 0), (self.gr_moving_average_xx_0, 0)) + self.connect((self.agc, 0), (self.pll, 0)) + self.connect((self.agc, 0), (self.rx_fft, 0)) + self.connect((self.gr_interleaved_short_to_complex_0, 0), (self.agc, 0)) + self.connect((self.throttle, 0), (self.gr_interleaved_short_to_complex_0, 0)) + self.connect((self.gr_file_source_0, 0), (self.throttle, 0)) + + def set_input_filename(self, input_filename): + self.input_filename = input_filename + + def set_decim(self, decim): + self.decim = decim + self.set_sample_rate(64e6/self.decim) + + def set_sym_rate(self, sym_rate): + self.sym_rate = sym_rate + self.set_sps(self.sample_rate/self.sym_rate) + self.demod_scope.set_sample_rate(self.sym_rate*2.0) + + def set_sample_rate(self, sample_rate): + self.sample_rate = sample_rate + self.set_max_carrier_offset(2*math.pi*100e3/self.sample_rate) + self.set_sps(self.sample_rate/self.sym_rate) + self.rx_fft.set_sample_rate(self.sample_rate) + + def set_config_filename(self, config_filename): + self.config_filename = config_filename + self._side_config = ConfigParser.ConfigParser() + self._side_config.read(self.config_filename) + if not self._side_config.has_section('usrp_rx_hrpt'): + self._side_config.add_section('usrp_rx_hrpt') + self._side_config.set('usrp_rx_hrpt', 'side', str(self.side)) + self._side_config.write(open(self.config_filename, 'w')) + self._saved_pll_alpha_config = ConfigParser.ConfigParser() + self._saved_pll_alpha_config.read(self.config_filename) + if not self._saved_pll_alpha_config.has_section('usrp_rx_hrpt'): + self._saved_pll_alpha_config.add_section('usrp_rx_hrpt') + self._saved_pll_alpha_config.set('usrp_rx_hrpt', 'pll_alpha', str(self.pll_alpha)) + self._saved_pll_alpha_config.write(open(self.config_filename, 'w')) + self._saved_clock_alpha_config = ConfigParser.ConfigParser() + self._saved_clock_alpha_config.read(self.config_filename) + if not self._saved_clock_alpha_config.has_section('usrp_rx_hrpt'): + self._saved_clock_alpha_config.add_section('usrp_rx_hrpt') + self._saved_clock_alpha_config.set('usrp_rx_hrpt', 'clock_alpha', str(self.clock_alpha)) + self._saved_clock_alpha_config.write(open(self.config_filename, 'w')) + self._output_filename_config = ConfigParser.ConfigParser() + self._output_filename_config.read(self.config_filename) + if not self._output_filename_config.has_section('usrp_rx_hrpt'): + self._output_filename_config.add_section('usrp_rx_hrpt') + self._output_filename_config.set('usrp_rx_hrpt', 'filename', str(self.output_filename)) + self._output_filename_config.write(open(self.config_filename, 'w')) + + def set_sps(self, sps): + self.sps = sps + self.set_hs(int(self.sps/2.0)) + self.gr_clock_recovery_mm_xx_0.set_omega(self.sps/2.0) + + def set_saved_pll_alpha(self, saved_pll_alpha): + self.saved_pll_alpha = saved_pll_alpha + self.set_pll_alpha(self.saved_pll_alpha) + + def set_saved_clock_alpha(self, saved_clock_alpha): + self.saved_clock_alpha = saved_clock_alpha + self.set_clock_alpha(self.saved_clock_alpha) + + def set_side(self, side): + self.side = side + self._side_config = ConfigParser.ConfigParser() + self._side_config.read(self.config_filename) + if not self._side_config.has_section('usrp_rx_hrpt'): + self._side_config.add_section('usrp_rx_hrpt') + self._side_config.set('usrp_rx_hrpt', 'side', str(self.side)) + self._side_config.write(open(self.config_filename, 'w')) + + def set_pll_alpha(self, pll_alpha): + self.pll_alpha = pll_alpha + self.pll.set_alpha(self.pll_alpha) + self.pll.set_beta(self.pll_alpha**2/4.0) + self._pll_alpha_slider.set_value(self.pll_alpha) + self._pll_alpha_text_box.set_value(self.pll_alpha) + self._saved_pll_alpha_config = ConfigParser.ConfigParser() + self._saved_pll_alpha_config.read(self.config_filename) + if not self._saved_pll_alpha_config.has_section('usrp_rx_hrpt'): + self._saved_pll_alpha_config.add_section('usrp_rx_hrpt') + self._saved_pll_alpha_config.set('usrp_rx_hrpt', 'pll_alpha', str(self.pll_alpha)) + self._saved_pll_alpha_config.write(open(self.config_filename, 'w')) + + def set_output_filename(self, output_filename): + self.output_filename = output_filename + self._output_filename_config = ConfigParser.ConfigParser() + self._output_filename_config.read(self.config_filename) + if not self._output_filename_config.has_section('usrp_rx_hrpt'): + self._output_filename_config.add_section('usrp_rx_hrpt') + self._output_filename_config.set('usrp_rx_hrpt', 'filename', str(self.output_filename)) + self._output_filename_config.write(open(self.config_filename, 'w')) + + def set_max_clock_offset(self, max_clock_offset): + self.max_clock_offset = max_clock_offset + + def set_max_carrier_offset(self, max_carrier_offset): + self.max_carrier_offset = max_carrier_offset + self.pll.set_max_offset(self.max_carrier_offset) + + def set_hs(self, hs): + self.hs = hs + self.gr_moving_average_xx_0.set_length_and_scale(self.hs, 1.0/self.hs) + + def set_clock_alpha(self, clock_alpha): + self.clock_alpha = clock_alpha + self.gr_clock_recovery_mm_xx_0.set_gain_omega(self.clock_alpha**2/4.0) + self.gr_clock_recovery_mm_xx_0.set_gain_mu(self.clock_alpha) + self._clock_alpha_slider.set_value(self.clock_alpha) + self._clock_alpha_text_box.set_value(self.clock_alpha) + self._saved_clock_alpha_config = ConfigParser.ConfigParser() + self._saved_clock_alpha_config.read(self.config_filename) + if not self._saved_clock_alpha_config.has_section('usrp_rx_hrpt'): + self._saved_clock_alpha_config.add_section('usrp_rx_hrpt') + self._saved_clock_alpha_config.set('usrp_rx_hrpt', 'clock_alpha', str(self.clock_alpha)) + self._saved_clock_alpha_config.write(open(self.config_filename, 'w')) + +if __name__ == '__main__': + parser = OptionParser(option_class=eng_option, usage="%prog: [options]") + parser.add_option("-F", "--input-filename", dest="input_filename", type="string", default='usrp.dat', + help="Set usrp.dat [default=%default]") + parser.add_option("-d", "--decim", dest="decim", type="intx", default=16, + help="Set decim [default=%default]") + (options, args) = parser.parse_args() + tb = file_rx_hrpt(input_filename=options.input_filename, decim=options.decim) + tb.Run(True) + diff --git a/gr-noaa/apps/usrp_rx_hrpt.cfg b/gr-noaa/apps/usrp_rx_hrpt.cfg deleted file mode 100644 index 69f3c0bf..00000000 --- a/gr-noaa/apps/usrp_rx_hrpt.cfg +++ /dev/null @@ -1,13 +0,0 @@ -[output] -filename = frames.dat - -[demod] -pll_alpha = 0.05 -sync_alpha = 0.05 - -[usrp] -freq = 1698000000.0 -decim = 16 -side = A -gain = 35.0 - diff --git a/gr-noaa/apps/usrp_rx_hrpt.grc b/gr-noaa/apps/usrp_rx_hrpt.grc index d0687971..da2f4178 100644 --- a/gr-noaa/apps/usrp_rx_hrpt.grc +++ b/gr-noaa/apps/usrp_rx_hrpt.grc @@ -1,6 +1,6 @@ - Sun Sep 27 13:37:22 2009 + Sun Nov 1 19:28:12 2009 options @@ -35,6 +35,10 @@ category Custom + + run_options + prompt + run True @@ -75,52 +79,6 @@ 0 - - import - - id - import_0 - - - _enabled - True - - - import - import math - - - _coordinate - (11, 76) - - - _rotation - 0 - - - - variable - - id - config_filename - - - _enabled - True - - - value - 'usrp_rx_hrpt.cfg' - - - _coordinate - (12, 129) - - - _rotation - 0 - - variable @@ -367,10 +325,10 @@ - variable_slider + variable_static_text id - sync_alpha + side_text _enabled @@ -378,35 +336,23 @@ label - SYNC Alpha + USRP Side value - saved_sync_alpha - - - min - 0.0 - - - max - 0.5 - - - num_steps - 100 + side - style - wx.SL_HORIZONTAL + converver + str_converter - converver - float_converter + formatter + None grid_pos - 0, 3, 1, 1 + 1, 0, 1, 1 notebook @@ -414,7 +360,7 @@ _coordinate - (618, 106) + (828, 20) _rotation @@ -425,7 +371,7 @@ variable_static_text id - side_text + decim_text _enabled @@ -433,15 +379,15 @@ label - USRP Side + Decimation value - side + decim converver - str_converter + float_converter formatter @@ -449,7 +395,7 @@ grid_pos - 1, 0, 1, 1 + 1, 1, 1, 1 notebook @@ -457,7 +403,7 @@ _coordinate - (828, 20) + (973, 20) _rotation @@ -465,10 +411,10 @@ - variable_config + variable id - side + config_filename _enabled @@ -476,31 +422,34 @@ value - 'A' + os.environ['HOME']+'/.gnuradio/config.conf' - type - string + _coordinate + (12, 129) - config_file - config_filename + _rotation + 0 + + + import - section - 'usrp' + id + import_0 - option - 'side' + _enabled + True - writeback - side + import + import math, os _coordinate - (194, 253) + (11, 76) _rotation @@ -511,7 +460,7 @@ variable_config id - decim + saved_freq _enabled @@ -519,7 +468,7 @@ value - 16 + 1698e6 type @@ -531,19 +480,19 @@ section - 'usrp' + 'usrp_rx_hrpt' option - 'decim' + 'freq' writeback - decim + freq _coordinate - (351, 255) + (507, 258) _rotation @@ -554,7 +503,7 @@ variable_config id - saved_freq + saved_gain _enabled @@ -562,7 +511,7 @@ value - 1698e6 + 35 type @@ -574,19 +523,19 @@ section - 'usrp' + 'usrp_rx_hrpt' option - 'freq' + 'gain' writeback - freq + gain _coordinate - (507, 258) + (664, 259) _rotation @@ -597,7 +546,7 @@ variable_config id - saved_gain + output_filename _enabled @@ -605,11 +554,11 @@ value - 35 + 'frames.dat' type - real + string config_file @@ -617,19 +566,19 @@ section - 'usrp' + 'usrp_rx_hrpt' option - 'gain' + 'filename' writeback - gain + output_filename _coordinate - (664, 259) + (1139, 259) _rotation @@ -637,10 +586,10 @@ - variable_config + variable id - saved_pll_alpha + max_clock_offset _enabled @@ -648,31 +597,66 @@ value - 0.05 + 0.1 - type - real + _coordinate + (705, 19) - config_file - config_filename + _rotation + 0 + + + variable_slider - section - 'demod' + id + clock_alpha - option - 'pll_alpha' + _enabled + True - writeback - pll_alpha + label + Clock Alpha + + + value + saved_clock_alpha + + + min + 0.0 + + + max + 0.5 + + + num_steps + 100 + + + style + wx.SL_HORIZONTAL + + + converver + float_converter + + + grid_pos + 0, 3, 1, 1 + + + notebook + _coordinate - (823, 258) + (618, 106) _rotation @@ -683,7 +667,7 @@ variable_config id - saved_sync_alpha + saved_pll_alpha _enabled @@ -703,19 +687,19 @@ section - 'demod' + 'usrp_rx_hrpt' option - 'sync_alpha' + 'pll_alpha' writeback - sync_alpha + pll_alpha _coordinate - (981, 258) + (823, 258) _rotation @@ -726,7 +710,7 @@ variable_config id - output_filename + saved_clock_alpha _enabled @@ -734,11 +718,11 @@ value - 'frames.dat' + 0.05 type - string + real config_file @@ -746,19 +730,19 @@ section - 'output' + 'usrp_rx_hrpt' option - 'filename' + 'clock_alpha' writeback - output_filename + clock_alpha _coordinate - (1139, 259) + (981, 258) _rotation @@ -766,42 +750,42 @@ - variable_static_text + variable_config id - decim_text + decim _enabled True - label - Decimation + value + 16 - value - decim + type + real - converver - float_converter + config_file + config_filename - formatter - None + section + 'usrp_rx_hrpt' - grid_pos - 1, 1, 1, 1 + option + 'decim' - notebook - + writeback + decim _coordinate - (973, 20) + (351, 255) _rotation @@ -809,10 +793,10 @@ - variable + variable_config id - max_sync_offset + side _enabled @@ -820,11 +804,31 @@ value - 0.01 + 'A' - _coordinate - (705, 19) + type + string + + + config_file + config_filename + + + section + 'usrp_rx_hrpt' + + + option + 'side' + + + writeback + side + + + _coordinate + (194, 253) _rotation @@ -847,11 +851,11 @@ labels - ['RX','Demod'] + ['Spectrum','Demod'] grid_pos - 2, 0, 1, 4 + 2,0,1,4 notebook @@ -859,7 +863,7 @@ _coordinate - (15, 237) + (12, 249) _rotation @@ -867,34 +871,49 @@ - noaa_hrpt_sync_fb + noaa_hrpt_deframer id - sync + deframer _enabled True - alpha - sync_alpha + _coordinate + (762, 975) - beta - sync_alpha**2/4.0 + _rotation + 0 + + + gr_file_sink - sps - sps + id + frame_sink - max_offset - max_sync_offset + _enabled + True + + + file + output_filename + + + type + short + + + vlen + 1 _coordinate - (840, 715) + (973, 1024) _rotation @@ -902,10 +921,10 @@ - noaa_hrpt_deframer + noaa_hrpt_bit_sync id - deframer + noaa_hrpt_bit_sync_0 _enabled @@ -913,7 +932,7 @@ _coordinate - (1071, 743) + (571, 975) _rotation @@ -921,10 +940,10 @@ - noaa_hrpt_decoder + gr_binary_slicer_fb id - decoder + gr_binary_slicer_fb_0 _enabled @@ -932,7 +951,7 @@ _coordinate - (1274, 743) + (393, 975) _rotation @@ -940,30 +959,22 @@ - gr_file_sink + virtual_source id - frame_sink + virtual_source_0 _enabled True - file - output_filename - - - type - short - - - vlen - 1 + stream_id + baseband _coordinate - (1273, 851) + (173, 971) _rotation @@ -971,53 +982,109 @@ - variable + wxgui_scopesink2 id - mf_taps + demod_scope _enabled True - value - [-0.5/hs,]*hs+[0.5/hs]*hs + type + float + + + title + Post-Demod + + + samp_rate + sym_rate*2.0 + + + v_scale + 0.5 + + + v_offset + 0 + + + t_scale + 10.0/sym_rate + + + ac_couple + False + + + xy_mode + False + + + num_inputs + 1 + + + win_size + + + + grid_pos + 0, 0, 1, 1 + + + notebook + displays, 1 _coordinate - (792, 158) + (666, 542) _rotation - 0 + 180 - noaa_hrpt_pll_cf + gr_clock_recovery_mm_xx id - pll + gr_clock_recovery_mm_xx_0 _enabled True - alpha - pll_alpha + type + float - beta - pll_alpha**2/4.0 + omega + sps/2.0 - max_offset - max_carrier_offset + gain_omega + clock_alpha**2/4.0 + + + mu + 0.5 + + + gain_mu + clock_alpha + + + omega_relative_limit + max_clock_offset _coordinate - (632, 723) + (873, 696) _rotation @@ -1025,10 +1092,10 @@ - gr_fir_filter_xxx + gr_moving_average_xx id - gr_fir_filter_xxx_0 + gr_moving_average_xx_0 _enabled @@ -1036,19 +1103,23 @@ type - ccc + float - decim - 1 + length + hs - taps - mf_taps + scale + 1.0/hs + + + max_iter + 4000 _coordinate - (400, 731) + (682, 713) _rotation @@ -1056,58 +1127,72 @@ - usrp_simple_source_x + noaa_hrpt_pll_cf id - usrp_source + pll _enabled True - type - complex + alpha + pll_alpha - format - + beta + pll_alpha**2/4.0 - which + max_offset + max_carrier_offset + + + _coordinate + (469, 713) + + + _rotation 0 + + + virtual_sink - decimation - decim + id + virtual_sink_0 - frequency - freq + _enabled + True - lo_offset - float('inf') + stream_id + baseband - gain - gain + _coordinate + (1142, 728) - side - side + _rotation + 0 + + + noaa_hrpt_decoder - rx_ant - RXA + id + decoder - hb_filters - + _enabled + True _coordinate - (28, 699) + (974, 925) _rotation @@ -1146,7 +1231,7 @@ _coordinate - (240, 715) + (301, 705) _rotation @@ -1154,10 +1239,10 @@ - wxgui_scopesink2 + usrp_simple_source_x id - rx_scope + usrp_source _enabled @@ -1168,44 +1253,44 @@ complex - title - RX Waveform + format + - samp_rate - sample_rate + which + 0 - v_scale - 0 + decimation + decim - t_scale - 20.0/sample_rate + frequency + freq - ac_couple - False + lo_offset + float('inf') - xy_mode - False + gain + gain - num_inputs - 1 + side + side - grid_pos - 1, 0, 1, 1 + rx_ant + RXA - notebook - displays, 0 + hb_filters + _coordinate - (406, 838) + (89, 689) _rotation @@ -1275,63 +1360,12 @@ 0.1 - grid_pos - 0, 0, 1, 1 - - - notebook - displays, 0 - - - _coordinate - (406, 466) - - - _rotation - 0 - - - - wxgui_scopesink2 - - id - pll_scope - - - _enabled - True - - - type - float - - - title - Demod Waveform - - - samp_rate - sample_rate - - - v_scale - 0.5 - - - t_scale - 20.0/sample_rate - - - ac_couple - False - - - xy_mode - False + win + None - num_inputs - 1 + win_size + 640, 360 grid_pos @@ -1339,67 +1373,73 @@ notebook - displays, 1 + displays, 0 _coordinate - (605, 552) + (477, 457) _rotation - 180 + 0 - deframer - frame_sink + noaa_hrpt_bit_sync_0 + deframer 0 0 - sync - deframer + gr_binary_slicer_fb_0 + noaa_hrpt_bit_sync_0 0 0 - pll - sync + virtual_source_0 + gr_binary_slicer_fb_0 0 0 - pll - pll_scope + deframer + frame_sink 0 0 - agc - rx_scope + deframer + decoder 0 0 - agc - rx_fft + gr_clock_recovery_mm_xx_0 + virtual_sink_0 0 0 - deframer - decoder + gr_clock_recovery_mm_xx_0 + demod_scope 0 0 - agc - gr_fir_filter_xxx_0 + gr_moving_average_xx_0 + gr_clock_recovery_mm_xx_0 + 0 + 0 + + + pll + gr_moving_average_xx_0 0 0 - gr_fir_filter_xxx_0 + agc pll 0 0 @@ -1410,4 +1450,10 @@ 0 0 + + agc + rx_fft + 0 + 0 + diff --git a/gr-noaa/apps/usrp_rx_hrpt.py b/gr-noaa/apps/usrp_rx_hrpt.py index ae70f25c..c1d0fd6e 100755 --- a/gr-noaa/apps/usrp_rx_hrpt.py +++ b/gr-noaa/apps/usrp_rx_hrpt.py @@ -2,12 +2,13 @@ ################################################## # Gnuradio Python Flow Graph # Title: USRP HRPT Receiver -# Generated: Sun Sep 27 13:37:23 2009 +# Generated: Sun Nov 1 19:28:13 2009 ################################################## from gnuradio import eng_notation from gnuradio import gr from gnuradio import noaa +from gnuradio import window from gnuradio.eng_option import eng_option from gnuradio.gr import firdes from gnuradio.wxgui import fftsink2 @@ -17,7 +18,7 @@ from grc_gnuradio import usrp as grc_usrp from grc_gnuradio import wxgui as grc_wxgui from optparse import OptionParser import ConfigParser -import math +import math, os import wx class usrp_rx_hrpt(grc_wxgui.top_block_gui): @@ -28,10 +29,10 @@ class usrp_rx_hrpt(grc_wxgui.top_block_gui): ################################################## # Variables ################################################## - self.config_filename = config_filename = 'usrp_rx_hrpt.cfg' + self.config_filename = config_filename = os.environ['HOME']+'/.gnuradio/config.conf' self._decim_config = ConfigParser.ConfigParser() self._decim_config.read(config_filename) - try: decim = self._decim_config.getfloat('usrp', 'decim') + try: decim = self._decim_config.getfloat('usrp_rx_hrpt', 'decim') except: decim = 16 self.decim = decim self.sym_rate = sym_rate = 600*1109 @@ -39,79 +40,55 @@ class usrp_rx_hrpt(grc_wxgui.top_block_gui): self.sps = sps = sample_rate/sym_rate self._side_config = ConfigParser.ConfigParser() self._side_config.read(config_filename) - try: side = self._side_config.get('usrp', 'side') + try: side = self._side_config.get('usrp_rx_hrpt', 'side') except: side = 'A' self.side = side - self._saved_sync_alpha_config = ConfigParser.ConfigParser() - self._saved_sync_alpha_config.read(config_filename) - try: saved_sync_alpha = self._saved_sync_alpha_config.getfloat('demod', 'sync_alpha') - except: saved_sync_alpha = 0.05 - self.saved_sync_alpha = saved_sync_alpha self._saved_pll_alpha_config = ConfigParser.ConfigParser() self._saved_pll_alpha_config.read(config_filename) - try: saved_pll_alpha = self._saved_pll_alpha_config.getfloat('demod', 'pll_alpha') + try: saved_pll_alpha = self._saved_pll_alpha_config.getfloat('usrp_rx_hrpt', 'pll_alpha') except: saved_pll_alpha = 0.05 self.saved_pll_alpha = saved_pll_alpha self._saved_gain_config = ConfigParser.ConfigParser() self._saved_gain_config.read(config_filename) - try: saved_gain = self._saved_gain_config.getfloat('usrp', 'gain') + try: saved_gain = self._saved_gain_config.getfloat('usrp_rx_hrpt', 'gain') except: saved_gain = 35 self.saved_gain = saved_gain self._saved_freq_config = ConfigParser.ConfigParser() self._saved_freq_config.read(config_filename) - try: saved_freq = self._saved_freq_config.getfloat('usrp', 'freq') + try: saved_freq = self._saved_freq_config.getfloat('usrp_rx_hrpt', 'freq') except: saved_freq = 1698e6 self.saved_freq = saved_freq - self.hs = hs = int(sps/2.0) - self.sync_alpha = sync_alpha = saved_sync_alpha + self._saved_clock_alpha_config = ConfigParser.ConfigParser() + self._saved_clock_alpha_config.read(config_filename) + try: saved_clock_alpha = self._saved_clock_alpha_config.getfloat('usrp_rx_hrpt', 'clock_alpha') + except: saved_clock_alpha = 0.05 + self.saved_clock_alpha = saved_clock_alpha self.side_text = side_text = side self.pll_alpha = pll_alpha = saved_pll_alpha self._output_filename_config = ConfigParser.ConfigParser() self._output_filename_config.read(config_filename) - try: output_filename = self._output_filename_config.get('output', 'filename') + try: output_filename = self._output_filename_config.get('usrp_rx_hrpt', 'filename') except: output_filename = 'frames.dat' self.output_filename = output_filename - self.mf_taps = mf_taps = [-0.5/hs,]*hs+[0.5/hs]*hs - self.max_sync_offset = max_sync_offset = 0.01 + self.max_clock_offset = max_clock_offset = 0.1 self.max_carrier_offset = max_carrier_offset = 2*math.pi*100e3/sample_rate + self.hs = hs = int(sps/2.0) self.gain = gain = saved_gain self.freq = freq = saved_freq self.decim_text = decim_text = decim + self.clock_alpha = clock_alpha = saved_clock_alpha ################################################## # Notebooks ################################################## self.displays = wx.Notebook(self.GetWin(), style=wx.NB_TOP) - self.displays.AddPage(grc_wxgui.Panel(self.displays), "RX") + self.displays.AddPage(grc_wxgui.Panel(self.displays), "Spectrum") self.displays.AddPage(grc_wxgui.Panel(self.displays), "Demod") self.GridAdd(self.displays, 2, 0, 1, 4) ################################################## # Controls ################################################## - _sync_alpha_sizer = wx.BoxSizer(wx.VERTICAL) - self._sync_alpha_text_box = forms.text_box( - parent=self.GetWin(), - sizer=_sync_alpha_sizer, - value=self.sync_alpha, - callback=self.set_sync_alpha, - label="SYNC Alpha", - converter=forms.float_converter(), - proportion=0, - ) - self._sync_alpha_slider = forms.slider( - parent=self.GetWin(), - sizer=_sync_alpha_sizer, - value=self.sync_alpha, - callback=self.set_sync_alpha, - minimum=0.0, - maximum=0.5, - num_steps=100, - style=wx.SL_HORIZONTAL, - cast=float, - proportion=1, - ) - self.GridAdd(_sync_alpha_sizer, 0, 3, 1, 1) self._side_text_static_text = forms.static_text( parent=self.GetWin(), value=self.side_text, @@ -182,6 +159,29 @@ class usrp_rx_hrpt(grc_wxgui.top_block_gui): converter=forms.float_converter(), ) self.GridAdd(self._decim_text_static_text, 1, 1, 1, 1) + _clock_alpha_sizer = wx.BoxSizer(wx.VERTICAL) + self._clock_alpha_text_box = forms.text_box( + parent=self.GetWin(), + sizer=_clock_alpha_sizer, + value=self.clock_alpha, + callback=self.set_clock_alpha, + label="Clock Alpha", + converter=forms.float_converter(), + proportion=0, + ) + self._clock_alpha_slider = forms.slider( + parent=self.GetWin(), + sizer=_clock_alpha_sizer, + value=self.clock_alpha, + callback=self.set_clock_alpha, + minimum=0.0, + maximum=0.5, + num_steps=100, + style=wx.SL_HORIZONTAL, + cast=float, + proportion=1, + ) + self.GridAdd(_clock_alpha_sizer, 0, 3, 1, 1) ################################################## # Blocks @@ -189,20 +189,24 @@ class usrp_rx_hrpt(grc_wxgui.top_block_gui): self.agc = gr.agc_cc(1e-6, 1.0, 1.0, 1.0) self.decoder = noaa.hrpt_decoder() self.deframer = noaa.hrpt_deframer() - self.frame_sink = gr.file_sink(gr.sizeof_short*1, output_filename) - self.gr_fir_filter_xxx_0 = gr.fir_filter_ccc(1, (mf_taps)) - self.pll = noaa.hrpt_pll_cf(pll_alpha, pll_alpha**2/4.0, max_carrier_offset) - self.pll_scope = scopesink2.scope_sink_f( + self.demod_scope = scopesink2.scope_sink_f( self.displays.GetPage(1).GetWin(), - title="Demod Waveform", - sample_rate=sample_rate, + title="Post-Demod", + sample_rate=sym_rate*2.0, v_scale=0.5, - t_scale=20.0/sample_rate, + v_offset=0, + t_scale=10.0/sym_rate, ac_couple=False, xy_mode=False, num_inputs=1, ) - self.displays.GetPage(1).GridAdd(self.pll_scope.win, 0, 0, 1, 1) + self.displays.GetPage(1).GridAdd(self.demod_scope.win, 0, 0, 1, 1) + self.frame_sink = gr.file_sink(gr.sizeof_short*1, output_filename) + self.gr_binary_slicer_fb_0 = gr.binary_slicer_fb() + self.gr_clock_recovery_mm_xx_0 = gr.clock_recovery_mm_ff(sps/2.0, clock_alpha**2/4.0, 0.5, clock_alpha, max_clock_offset) + self.gr_moving_average_xx_0 = gr.moving_average_ff(hs, 1.0/hs, 4000) + self.noaa_hrpt_bit_sync_0 = noaa.hrpt_bit_sync() + self.pll = noaa.hrpt_pll_cf(pll_alpha, pll_alpha**2/4.0, max_carrier_offset) self.rx_fft = fftsink2.fft_sink_c( self.displays.GetPage(0).GetWin(), baseband_freq=freq, @@ -217,20 +221,9 @@ class usrp_rx_hrpt(grc_wxgui.top_block_gui): avg_alpha=0.1, title="RX Spectrum", peak_hold=False, + size=(640, 360), ) self.displays.GetPage(0).GridAdd(self.rx_fft.win, 0, 0, 1, 1) - self.rx_scope = scopesink2.scope_sink_c( - self.displays.GetPage(0).GetWin(), - title="RX Waveform", - sample_rate=sample_rate, - v_scale=0, - t_scale=20.0/sample_rate, - ac_couple=False, - xy_mode=False, - num_inputs=1, - ) - self.displays.GetPage(0).GridAdd(self.rx_scope.win, 1, 0, 1, 1) - self.sync = noaa.hrpt_sync_fb(sync_alpha, sync_alpha**2/4.0, sps, max_sync_offset) self.usrp_source = grc_usrp.simple_source_c(which=0, side=side, rx_ant="RXA") self.usrp_source.set_decim_rate(decim) self.usrp_source.set_frequency(freq, verbose=True) @@ -239,104 +232,101 @@ class usrp_rx_hrpt(grc_wxgui.top_block_gui): ################################################## # Connections ################################################## + self.connect((self.noaa_hrpt_bit_sync_0, 0), (self.deframer, 0)) + self.connect((self.gr_binary_slicer_fb_0, 0), (self.noaa_hrpt_bit_sync_0, 0)) + self.connect((self.gr_clock_recovery_mm_xx_0, 0), (self.gr_binary_slicer_fb_0, 0)) self.connect((self.deframer, 0), (self.frame_sink, 0)) - self.connect((self.sync, 0), (self.deframer, 0)) - self.connect((self.pll, 0), (self.sync, 0)) - self.connect((self.pll, 0), (self.pll_scope, 0)) - self.connect((self.agc, 0), (self.rx_scope, 0)) - self.connect((self.agc, 0), (self.rx_fft, 0)) self.connect((self.deframer, 0), (self.decoder, 0)) - self.connect((self.agc, 0), (self.gr_fir_filter_xxx_0, 0)) - self.connect((self.gr_fir_filter_xxx_0, 0), (self.pll, 0)) + self.connect((self.gr_clock_recovery_mm_xx_0, 0), (self.demod_scope, 0)) + self.connect((self.gr_moving_average_xx_0, 0), (self.gr_clock_recovery_mm_xx_0, 0)) + self.connect((self.pll, 0), (self.gr_moving_average_xx_0, 0)) + self.connect((self.agc, 0), (self.pll, 0)) self.connect((self.usrp_source, 0), (self.agc, 0)) + self.connect((self.agc, 0), (self.rx_fft, 0)) def set_config_filename(self, config_filename): self.config_filename = config_filename - self._side_config = ConfigParser.ConfigParser() - self._side_config.read(self.config_filename) - if not self._side_config.has_section('usrp'): - self._side_config.add_section('usrp') - self._side_config.set('usrp', 'side', str(self.side)) - self._side_config.write(open(self.config_filename, 'w')) - self._decim_config = ConfigParser.ConfigParser() - self._decim_config.read(self.config_filename) - if not self._decim_config.has_section('usrp'): - self._decim_config.add_section('usrp') - self._decim_config.set('usrp', 'decim', str(self.decim)) - self._decim_config.write(open(self.config_filename, 'w')) self._saved_freq_config = ConfigParser.ConfigParser() self._saved_freq_config.read(self.config_filename) - if not self._saved_freq_config.has_section('usrp'): - self._saved_freq_config.add_section('usrp') - self._saved_freq_config.set('usrp', 'freq', str(self.freq)) + if not self._saved_freq_config.has_section('usrp_rx_hrpt'): + self._saved_freq_config.add_section('usrp_rx_hrpt') + self._saved_freq_config.set('usrp_rx_hrpt', 'freq', str(self.freq)) self._saved_freq_config.write(open(self.config_filename, 'w')) self._saved_gain_config = ConfigParser.ConfigParser() self._saved_gain_config.read(self.config_filename) - if not self._saved_gain_config.has_section('usrp'): - self._saved_gain_config.add_section('usrp') - self._saved_gain_config.set('usrp', 'gain', str(self.gain)) + if not self._saved_gain_config.has_section('usrp_rx_hrpt'): + self._saved_gain_config.add_section('usrp_rx_hrpt') + self._saved_gain_config.set('usrp_rx_hrpt', 'gain', str(self.gain)) self._saved_gain_config.write(open(self.config_filename, 'w')) - self._saved_pll_alpha_config = ConfigParser.ConfigParser() - self._saved_pll_alpha_config.read(self.config_filename) - if not self._saved_pll_alpha_config.has_section('demod'): - self._saved_pll_alpha_config.add_section('demod') - self._saved_pll_alpha_config.set('demod', 'pll_alpha', str(self.pll_alpha)) - self._saved_pll_alpha_config.write(open(self.config_filename, 'w')) - self._saved_sync_alpha_config = ConfigParser.ConfigParser() - self._saved_sync_alpha_config.read(self.config_filename) - if not self._saved_sync_alpha_config.has_section('demod'): - self._saved_sync_alpha_config.add_section('demod') - self._saved_sync_alpha_config.set('demod', 'sync_alpha', str(self.sync_alpha)) - self._saved_sync_alpha_config.write(open(self.config_filename, 'w')) self._output_filename_config = ConfigParser.ConfigParser() self._output_filename_config.read(self.config_filename) - if not self._output_filename_config.has_section('output'): - self._output_filename_config.add_section('output') - self._output_filename_config.set('output', 'filename', str(self.output_filename)) + if not self._output_filename_config.has_section('usrp_rx_hrpt'): + self._output_filename_config.add_section('usrp_rx_hrpt') + self._output_filename_config.set('usrp_rx_hrpt', 'filename', str(self.output_filename)) self._output_filename_config.write(open(self.config_filename, 'w')) + self._saved_pll_alpha_config = ConfigParser.ConfigParser() + self._saved_pll_alpha_config.read(self.config_filename) + if not self._saved_pll_alpha_config.has_section('usrp_rx_hrpt'): + self._saved_pll_alpha_config.add_section('usrp_rx_hrpt') + self._saved_pll_alpha_config.set('usrp_rx_hrpt', 'pll_alpha', str(self.pll_alpha)) + self._saved_pll_alpha_config.write(open(self.config_filename, 'w')) + self._saved_clock_alpha_config = ConfigParser.ConfigParser() + self._saved_clock_alpha_config.read(self.config_filename) + if not self._saved_clock_alpha_config.has_section('usrp_rx_hrpt'): + self._saved_clock_alpha_config.add_section('usrp_rx_hrpt') + self._saved_clock_alpha_config.set('usrp_rx_hrpt', 'clock_alpha', str(self.clock_alpha)) + self._saved_clock_alpha_config.write(open(self.config_filename, 'w')) + self._decim_config = ConfigParser.ConfigParser() + self._decim_config.read(self.config_filename) + if not self._decim_config.has_section('usrp_rx_hrpt'): + self._decim_config.add_section('usrp_rx_hrpt') + self._decim_config.set('usrp_rx_hrpt', 'decim', str(self.decim)) + self._decim_config.write(open(self.config_filename, 'w')) + self._side_config = ConfigParser.ConfigParser() + self._side_config.read(self.config_filename) + if not self._side_config.has_section('usrp_rx_hrpt'): + self._side_config.add_section('usrp_rx_hrpt') + self._side_config.set('usrp_rx_hrpt', 'side', str(self.side)) + self._side_config.write(open(self.config_filename, 'w')) def set_decim(self, decim): self.decim = decim self.set_sample_rate(64e6/self.decim) + self.set_decim_text(self.decim) self._decim_config = ConfigParser.ConfigParser() self._decim_config.read(self.config_filename) - if not self._decim_config.has_section('usrp'): - self._decim_config.add_section('usrp') - self._decim_config.set('usrp', 'decim', str(self.decim)) + if not self._decim_config.has_section('usrp_rx_hrpt'): + self._decim_config.add_section('usrp_rx_hrpt') + self._decim_config.set('usrp_rx_hrpt', 'decim', str(self.decim)) self._decim_config.write(open(self.config_filename, 'w')) - self.set_decim_text(self.decim) self.usrp_source.set_decim_rate(self.decim) def set_sym_rate(self, sym_rate): self.sym_rate = sym_rate self.set_sps(self.sample_rate/self.sym_rate) + self.demod_scope.set_sample_rate(self.sym_rate*2.0) def set_sample_rate(self, sample_rate): self.sample_rate = sample_rate self.set_max_carrier_offset(2*math.pi*100e3/self.sample_rate) self.set_sps(self.sample_rate/self.sym_rate) - self.rx_scope.set_sample_rate(self.sample_rate) self.rx_fft.set_sample_rate(self.sample_rate) - self.pll_scope.set_sample_rate(self.sample_rate) def set_sps(self, sps): self.sps = sps self.set_hs(int(self.sps/2.0)) + self.gr_clock_recovery_mm_xx_0.set_omega(self.sps/2.0) def set_side(self, side): self.side = side self.set_side_text(self.side) self._side_config = ConfigParser.ConfigParser() self._side_config.read(self.config_filename) - if not self._side_config.has_section('usrp'): - self._side_config.add_section('usrp') - self._side_config.set('usrp', 'side', str(self.side)) + if not self._side_config.has_section('usrp_rx_hrpt'): + self._side_config.add_section('usrp_rx_hrpt') + self._side_config.set('usrp_rx_hrpt', 'side', str(self.side)) self._side_config.write(open(self.config_filename, 'w')) - def set_saved_sync_alpha(self, saved_sync_alpha): - self.saved_sync_alpha = saved_sync_alpha - self.set_sync_alpha(self.saved_sync_alpha) - def set_saved_pll_alpha(self, saved_pll_alpha): self.saved_pll_alpha = saved_pll_alpha self.set_pll_alpha(self.saved_pll_alpha) @@ -349,22 +339,9 @@ class usrp_rx_hrpt(grc_wxgui.top_block_gui): self.saved_freq = saved_freq self.set_freq(self.saved_freq) - def set_hs(self, hs): - self.hs = hs - self.set_mf_taps([-0.5/self.hs,]*self.hs+[0.5/self.hs]*self.hs) - - def set_sync_alpha(self, sync_alpha): - self.sync_alpha = sync_alpha - self._sync_alpha_slider.set_value(self.sync_alpha) - self._sync_alpha_text_box.set_value(self.sync_alpha) - self._saved_sync_alpha_config = ConfigParser.ConfigParser() - self._saved_sync_alpha_config.read(self.config_filename) - if not self._saved_sync_alpha_config.has_section('demod'): - self._saved_sync_alpha_config.add_section('demod') - self._saved_sync_alpha_config.set('demod', 'sync_alpha', str(self.sync_alpha)) - self._saved_sync_alpha_config.write(open(self.config_filename, 'w')) - self.sync.set_alpha(self.sync_alpha) - self.sync.set_beta(self.sync_alpha**2/4.0) + def set_saved_clock_alpha(self, saved_clock_alpha): + self.saved_clock_alpha = saved_clock_alpha + self.set_clock_alpha(self.saved_clock_alpha) def set_side_text(self, side_text): self.side_text = side_text @@ -376,9 +353,9 @@ class usrp_rx_hrpt(grc_wxgui.top_block_gui): self._pll_alpha_text_box.set_value(self.pll_alpha) self._saved_pll_alpha_config = ConfigParser.ConfigParser() self._saved_pll_alpha_config.read(self.config_filename) - if not self._saved_pll_alpha_config.has_section('demod'): - self._saved_pll_alpha_config.add_section('demod') - self._saved_pll_alpha_config.set('demod', 'pll_alpha', str(self.pll_alpha)) + if not self._saved_pll_alpha_config.has_section('usrp_rx_hrpt'): + self._saved_pll_alpha_config.add_section('usrp_rx_hrpt') + self._saved_pll_alpha_config.set('usrp_rx_hrpt', 'pll_alpha', str(self.pll_alpha)) self._saved_pll_alpha_config.write(open(self.config_filename, 'w')) self.pll.set_alpha(self.pll_alpha) self.pll.set_beta(self.pll_alpha**2/4.0) @@ -387,32 +364,31 @@ class usrp_rx_hrpt(grc_wxgui.top_block_gui): self.output_filename = output_filename self._output_filename_config = ConfigParser.ConfigParser() self._output_filename_config.read(self.config_filename) - if not self._output_filename_config.has_section('output'): - self._output_filename_config.add_section('output') - self._output_filename_config.set('output', 'filename', str(self.output_filename)) + if not self._output_filename_config.has_section('usrp_rx_hrpt'): + self._output_filename_config.add_section('usrp_rx_hrpt') + self._output_filename_config.set('usrp_rx_hrpt', 'filename', str(self.output_filename)) self._output_filename_config.write(open(self.config_filename, 'w')) - def set_mf_taps(self, mf_taps): - self.mf_taps = mf_taps - self.gr_fir_filter_xxx_0.set_taps((self.mf_taps)) - - def set_max_sync_offset(self, max_sync_offset): - self.max_sync_offset = max_sync_offset - self.sync.set_max_offset(self.max_sync_offset) + def set_max_clock_offset(self, max_clock_offset): + self.max_clock_offset = max_clock_offset def set_max_carrier_offset(self, max_carrier_offset): self.max_carrier_offset = max_carrier_offset self.pll.set_max_offset(self.max_carrier_offset) + def set_hs(self, hs): + self.hs = hs + self.gr_moving_average_xx_0.set_length_and_scale(self.hs, 1.0/self.hs) + def set_gain(self, gain): self.gain = gain self._gain_slider.set_value(self.gain) self._gain_text_box.set_value(self.gain) self._saved_gain_config = ConfigParser.ConfigParser() self._saved_gain_config.read(self.config_filename) - if not self._saved_gain_config.has_section('usrp'): - self._saved_gain_config.add_section('usrp') - self._saved_gain_config.set('usrp', 'gain', str(self.gain)) + if not self._saved_gain_config.has_section('usrp_rx_hrpt'): + self._saved_gain_config.add_section('usrp_rx_hrpt') + self._saved_gain_config.set('usrp_rx_hrpt', 'gain', str(self.gain)) self._saved_gain_config.write(open(self.config_filename, 'w')) self.usrp_source.set_gain(self.gain) @@ -421,9 +397,9 @@ class usrp_rx_hrpt(grc_wxgui.top_block_gui): self._freq_text_box.set_value(self.freq) self._saved_freq_config = ConfigParser.ConfigParser() self._saved_freq_config.read(self.config_filename) - if not self._saved_freq_config.has_section('usrp'): - self._saved_freq_config.add_section('usrp') - self._saved_freq_config.set('usrp', 'freq', str(self.freq)) + if not self._saved_freq_config.has_section('usrp_rx_hrpt'): + self._saved_freq_config.add_section('usrp_rx_hrpt') + self._saved_freq_config.set('usrp_rx_hrpt', 'freq', str(self.freq)) self._saved_freq_config.write(open(self.config_filename, 'w')) self.usrp_source.set_frequency(self.freq) self.rx_fft.set_baseband_freq(self.freq) @@ -432,6 +408,19 @@ class usrp_rx_hrpt(grc_wxgui.top_block_gui): self.decim_text = decim_text self._decim_text_static_text.set_value(self.decim_text) + def set_clock_alpha(self, clock_alpha): + self.clock_alpha = clock_alpha + self._clock_alpha_slider.set_value(self.clock_alpha) + self._clock_alpha_text_box.set_value(self.clock_alpha) + self._saved_clock_alpha_config = ConfigParser.ConfigParser() + self._saved_clock_alpha_config.read(self.config_filename) + if not self._saved_clock_alpha_config.has_section('usrp_rx_hrpt'): + self._saved_clock_alpha_config.add_section('usrp_rx_hrpt') + self._saved_clock_alpha_config.set('usrp_rx_hrpt', 'clock_alpha', str(self.clock_alpha)) + self._saved_clock_alpha_config.write(open(self.config_filename, 'w')) + self.gr_clock_recovery_mm_xx_0.set_gain_omega(self.clock_alpha**2/4.0) + self.gr_clock_recovery_mm_xx_0.set_gain_mu(self.clock_alpha) + if __name__ == '__main__': parser = OptionParser(option_class=eng_option, usage="%prog: [options]") (options, args) = parser.parse_args() diff --git a/gr-noaa/apps/usrp_rx_hrpt2.py b/gr-noaa/apps/usrp_rx_hrpt2.py deleted file mode 100755 index 31933516..00000000 --- a/gr-noaa/apps/usrp_rx_hrpt2.py +++ /dev/null @@ -1,401 +0,0 @@ -#!/usr/bin/env python -################################################## -# Gnuradio Python Flow Graph -# Title: USRP HRPT Receiver -# Generated: Sun Sep 27 13:32:48 2009 -################################################## - -from gnuradio import eng_notation -from gnuradio import gr -from gnuradio import noaa -from gnuradio.eng_option import eng_option -from gnuradio.gr import firdes -from gnuradio.wxgui import forms -from gnuradio.wxgui import scopesink2 -from grc_gnuradio import usrp as grc_usrp -from grc_gnuradio import wxgui as grc_wxgui -from optparse import OptionParser -import ConfigParser -import math -import wx - -class usrp_rx_hrpt2(grc_wxgui.top_block_gui): - - def __init__(self): - grc_wxgui.top_block_gui.__init__(self, title="USRP HRPT Receiver") - - ################################################## - # Variables - ################################################## - self.config_filename = config_filename = 'usrp_rx_hrpt.cfg' - self._decim_config = ConfigParser.ConfigParser() - self._decim_config.read(config_filename) - try: decim = self._decim_config.getfloat('usrp', 'decim') - except: decim = 16 - self.decim = decim - self.sym_rate = sym_rate = 600*1109 - self.sample_rate = sample_rate = 64e6/decim - self.sps = sps = sample_rate/sym_rate - self._side_config = ConfigParser.ConfigParser() - self._side_config.read(config_filename) - try: side = self._side_config.get('usrp', 'side') - except: side = 'A' - self.side = side - self._saved_sync_alpha_config = ConfigParser.ConfigParser() - self._saved_sync_alpha_config.read(config_filename) - try: saved_sync_alpha = self._saved_sync_alpha_config.getfloat('demod', 'sync_alpha') - except: saved_sync_alpha = 0.05 - self.saved_sync_alpha = saved_sync_alpha - self._saved_pll_alpha_config = ConfigParser.ConfigParser() - self._saved_pll_alpha_config.read(config_filename) - try: saved_pll_alpha = self._saved_pll_alpha_config.getfloat('demod', 'pll_alpha') - except: saved_pll_alpha = 0.05 - self.saved_pll_alpha = saved_pll_alpha - self._saved_gain_config = ConfigParser.ConfigParser() - self._saved_gain_config.read(config_filename) - try: saved_gain = self._saved_gain_config.getfloat('usrp', 'gain') - except: saved_gain = 35 - self.saved_gain = saved_gain - self._saved_freq_config = ConfigParser.ConfigParser() - self._saved_freq_config.read(config_filename) - try: saved_freq = self._saved_freq_config.getfloat('usrp', 'freq') - except: saved_freq = 1698e6 - self.saved_freq = saved_freq - self.hs = hs = int(sps/2.0) - self.sync_alpha = sync_alpha = saved_sync_alpha - self.side_text = side_text = side - self.pll_alpha = pll_alpha = saved_pll_alpha - self._output_filename_config = ConfigParser.ConfigParser() - self._output_filename_config.read(config_filename) - try: output_filename = self._output_filename_config.get('output', 'filename') - except: output_filename = 'frames.dat' - self.output_filename = output_filename - self.mf_taps = mf_taps = [-0.5/hs,]*hs+[0.5/hs,]*hs - self.max_sync_offset = max_sync_offset = 0.01 - self.max_carrier_offset = max_carrier_offset = 2*math.pi*100e3/sample_rate - self.gain = gain = saved_gain - self.freq = freq = saved_freq - self.decim_text = decim_text = decim - - ################################################## - # Controls - ################################################## - _sync_alpha_sizer = wx.BoxSizer(wx.VERTICAL) - self._sync_alpha_text_box = forms.text_box( - parent=self.GetWin(), - sizer=_sync_alpha_sizer, - value=self.sync_alpha, - callback=self.set_sync_alpha, - label="SYNC Alpha", - converter=forms.float_converter(), - proportion=0, - ) - self._sync_alpha_slider = forms.slider( - parent=self.GetWin(), - sizer=_sync_alpha_sizer, - value=self.sync_alpha, - callback=self.set_sync_alpha, - minimum=0.0, - maximum=0.5, - num_steps=100, - style=wx.SL_HORIZONTAL, - cast=float, - proportion=1, - ) - self.GridAdd(_sync_alpha_sizer, 0, 3, 1, 1) - self._side_text_static_text = forms.static_text( - parent=self.GetWin(), - value=self.side_text, - callback=self.set_side_text, - label="USRP Side", - converter=forms.str_converter(), - ) - self.GridAdd(self._side_text_static_text, 1, 0, 1, 1) - _pll_alpha_sizer = wx.BoxSizer(wx.VERTICAL) - self._pll_alpha_text_box = forms.text_box( - parent=self.GetWin(), - sizer=_pll_alpha_sizer, - value=self.pll_alpha, - callback=self.set_pll_alpha, - label="PLL Alpha", - converter=forms.float_converter(), - proportion=0, - ) - self._pll_alpha_slider = forms.slider( - parent=self.GetWin(), - sizer=_pll_alpha_sizer, - value=self.pll_alpha, - callback=self.set_pll_alpha, - minimum=0.0, - maximum=0.5, - num_steps=100, - style=wx.SL_HORIZONTAL, - cast=float, - proportion=1, - ) - self.GridAdd(_pll_alpha_sizer, 0, 2, 1, 1) - _gain_sizer = wx.BoxSizer(wx.VERTICAL) - self._gain_text_box = forms.text_box( - parent=self.GetWin(), - sizer=_gain_sizer, - value=self.gain, - callback=self.set_gain, - label="RX Gain", - converter=forms.float_converter(), - proportion=0, - ) - self._gain_slider = forms.slider( - parent=self.GetWin(), - sizer=_gain_sizer, - value=self.gain, - callback=self.set_gain, - minimum=0, - maximum=100, - num_steps=100, - style=wx.SL_HORIZONTAL, - cast=float, - proportion=1, - ) - self.GridAdd(_gain_sizer, 0, 1, 1, 1) - self._freq_text_box = forms.text_box( - parent=self.GetWin(), - value=self.freq, - callback=self.set_freq, - label="Frequency", - converter=forms.float_converter(), - ) - self.GridAdd(self._freq_text_box, 0, 0, 1, 1) - self._decim_text_static_text = forms.static_text( - parent=self.GetWin(), - value=self.decim_text, - callback=self.set_decim_text, - label="Decimation", - converter=forms.float_converter(), - ) - self.GridAdd(self._decim_text_static_text, 1, 1, 1, 1) - - ################################################## - # Blocks - ################################################## - self.agc = gr.agc_cc(1e-6, 1.0, 1.0, 1.0) - self.decoder = noaa.hrpt_decoder() - self.deframer = noaa.hrpt_deframer() - self.frame_sink = gr.file_sink(gr.sizeof_short*1, output_filename) - self.gr_fir_filter_xxx_0 = gr.fir_filter_ccc(1, (mf_taps)) - self.pll = noaa.hrpt_pll_cf(pll_alpha, pll_alpha**2/4.0, max_carrier_offset) - self.pll_scope = scopesink2.scope_sink_f( - self.GetWin(), - title="Demod Waveform", - sample_rate=sample_rate, - v_scale=0.5, - t_scale=20.0/sample_rate, - ac_couple=False, - xy_mode=False, - num_inputs=1, - ) - self.GridAdd(self.pll_scope.win, 2, 0, 1, 4) - self.sync = noaa.hrpt_sync_fb(sync_alpha, sync_alpha**2/4.0, sps, max_sync_offset) - self.usrp_source = grc_usrp.simple_source_c(which=0, side=side, rx_ant="RXA") - self.usrp_source.set_decim_rate(decim) - self.usrp_source.set_frequency(freq, verbose=True) - self.usrp_source.set_gain(gain) - - ################################################## - # Connections - ################################################## - self.connect((self.gr_fir_filter_xxx_0, 0), (self.pll, 0)) - self.connect((self.agc, 0), (self.gr_fir_filter_xxx_0, 0)) - self.connect((self.usrp_source, 0), (self.agc, 0)) - self.connect((self.deframer, 0), (self.decoder, 0)) - self.connect((self.pll, 0), (self.pll_scope, 0)) - self.connect((self.pll, 0), (self.sync, 0)) - self.connect((self.sync, 0), (self.deframer, 0)) - self.connect((self.deframer, 0), (self.frame_sink, 0)) - - def set_config_filename(self, config_filename): - self.config_filename = config_filename - self._side_config = ConfigParser.ConfigParser() - self._side_config.read(self.config_filename) - if not self._side_config.has_section('usrp'): - self._side_config.add_section('usrp') - self._side_config.set('usrp', 'side', str(self.side)) - self._side_config.write(open(self.config_filename, 'w')) - self._decim_config = ConfigParser.ConfigParser() - self._decim_config.read(self.config_filename) - if not self._decim_config.has_section('usrp'): - self._decim_config.add_section('usrp') - self._decim_config.set('usrp', 'decim', str(self.decim)) - self._decim_config.write(open(self.config_filename, 'w')) - self._saved_freq_config = ConfigParser.ConfigParser() - self._saved_freq_config.read(self.config_filename) - if not self._saved_freq_config.has_section('usrp'): - self._saved_freq_config.add_section('usrp') - self._saved_freq_config.set('usrp', 'freq', str(self.freq)) - self._saved_freq_config.write(open(self.config_filename, 'w')) - self._saved_gain_config = ConfigParser.ConfigParser() - self._saved_gain_config.read(self.config_filename) - if not self._saved_gain_config.has_section('usrp'): - self._saved_gain_config.add_section('usrp') - self._saved_gain_config.set('usrp', 'gain', str(self.gain)) - self._saved_gain_config.write(open(self.config_filename, 'w')) - self._saved_pll_alpha_config = ConfigParser.ConfigParser() - self._saved_pll_alpha_config.read(self.config_filename) - if not self._saved_pll_alpha_config.has_section('demod'): - self._saved_pll_alpha_config.add_section('demod') - self._saved_pll_alpha_config.set('demod', 'pll_alpha', str(self.pll_alpha)) - self._saved_pll_alpha_config.write(open(self.config_filename, 'w')) - self._saved_sync_alpha_config = ConfigParser.ConfigParser() - self._saved_sync_alpha_config.read(self.config_filename) - if not self._saved_sync_alpha_config.has_section('demod'): - self._saved_sync_alpha_config.add_section('demod') - self._saved_sync_alpha_config.set('demod', 'sync_alpha', str(self.sync_alpha)) - self._saved_sync_alpha_config.write(open(self.config_filename, 'w')) - self._output_filename_config = ConfigParser.ConfigParser() - self._output_filename_config.read(self.config_filename) - if not self._output_filename_config.has_section('output'): - self._output_filename_config.add_section('output') - self._output_filename_config.set('output', 'filename', str(self.output_filename)) - self._output_filename_config.write(open(self.config_filename, 'w')) - - def set_decim(self, decim): - self.decim = decim - self.set_sample_rate(64e6/self.decim) - self._decim_config = ConfigParser.ConfigParser() - self._decim_config.read(self.config_filename) - if not self._decim_config.has_section('usrp'): - self._decim_config.add_section('usrp') - self._decim_config.set('usrp', 'decim', str(self.decim)) - self._decim_config.write(open(self.config_filename, 'w')) - self.set_decim_text(self.decim) - self.usrp_source.set_decim_rate(self.decim) - - def set_sym_rate(self, sym_rate): - self.sym_rate = sym_rate - self.set_sps(self.sample_rate/self.sym_rate) - - def set_sample_rate(self, sample_rate): - self.sample_rate = sample_rate - self.set_max_carrier_offset(2*math.pi*100e3/self.sample_rate) - self.set_sps(self.sample_rate/self.sym_rate) - self.pll_scope.set_sample_rate(self.sample_rate) - - def set_sps(self, sps): - self.sps = sps - self.set_hs(int(self.sps/2.0)) - - def set_side(self, side): - self.side = side - self.set_side_text(self.side) - self._side_config = ConfigParser.ConfigParser() - self._side_config.read(self.config_filename) - if not self._side_config.has_section('usrp'): - self._side_config.add_section('usrp') - self._side_config.set('usrp', 'side', str(self.side)) - self._side_config.write(open(self.config_filename, 'w')) - - def set_saved_sync_alpha(self, saved_sync_alpha): - self.saved_sync_alpha = saved_sync_alpha - self.set_sync_alpha(self.saved_sync_alpha) - - def set_saved_pll_alpha(self, saved_pll_alpha): - self.saved_pll_alpha = saved_pll_alpha - self.set_pll_alpha(self.saved_pll_alpha) - - def set_saved_gain(self, saved_gain): - self.saved_gain = saved_gain - self.set_gain(self.saved_gain) - - def set_saved_freq(self, saved_freq): - self.saved_freq = saved_freq - self.set_freq(self.saved_freq) - - def set_hs(self, hs): - self.hs = hs - self.set_mf_taps([-0.5/self.hs,]*self.hs+[0.5/self.hs,]*self.hs) - - def set_sync_alpha(self, sync_alpha): - self.sync_alpha = sync_alpha - self._sync_alpha_slider.set_value(self.sync_alpha) - self._sync_alpha_text_box.set_value(self.sync_alpha) - self._saved_sync_alpha_config = ConfigParser.ConfigParser() - self._saved_sync_alpha_config.read(self.config_filename) - if not self._saved_sync_alpha_config.has_section('demod'): - self._saved_sync_alpha_config.add_section('demod') - self._saved_sync_alpha_config.set('demod', 'sync_alpha', str(self.sync_alpha)) - self._saved_sync_alpha_config.write(open(self.config_filename, 'w')) - self.sync.set_alpha(self.sync_alpha) - self.sync.set_beta(self.sync_alpha**2/4.0) - - def set_side_text(self, side_text): - self.side_text = side_text - self._side_text_static_text.set_value(self.side_text) - - def set_pll_alpha(self, pll_alpha): - self.pll_alpha = pll_alpha - self._pll_alpha_slider.set_value(self.pll_alpha) - self._pll_alpha_text_box.set_value(self.pll_alpha) - self._saved_pll_alpha_config = ConfigParser.ConfigParser() - self._saved_pll_alpha_config.read(self.config_filename) - if not self._saved_pll_alpha_config.has_section('demod'): - self._saved_pll_alpha_config.add_section('demod') - self._saved_pll_alpha_config.set('demod', 'pll_alpha', str(self.pll_alpha)) - self._saved_pll_alpha_config.write(open(self.config_filename, 'w')) - self.pll.set_alpha(self.pll_alpha) - self.pll.set_beta(self.pll_alpha**2/4.0) - - def set_output_filename(self, output_filename): - self.output_filename = output_filename - self._output_filename_config = ConfigParser.ConfigParser() - self._output_filename_config.read(self.config_filename) - if not self._output_filename_config.has_section('output'): - self._output_filename_config.add_section('output') - self._output_filename_config.set('output', 'filename', str(self.output_filename)) - self._output_filename_config.write(open(self.config_filename, 'w')) - - def set_mf_taps(self, mf_taps): - self.mf_taps = mf_taps - self.gr_fir_filter_xxx_0.set_taps((self.mf_taps)) - - def set_max_sync_offset(self, max_sync_offset): - self.max_sync_offset = max_sync_offset - self.sync.set_max_offset(self.max_sync_offset) - - def set_max_carrier_offset(self, max_carrier_offset): - self.max_carrier_offset = max_carrier_offset - self.pll.set_max_offset(self.max_carrier_offset) - - def set_gain(self, gain): - self.gain = gain - self._gain_slider.set_value(self.gain) - self._gain_text_box.set_value(self.gain) - self._saved_gain_config = ConfigParser.ConfigParser() - self._saved_gain_config.read(self.config_filename) - if not self._saved_gain_config.has_section('usrp'): - self._saved_gain_config.add_section('usrp') - self._saved_gain_config.set('usrp', 'gain', str(self.gain)) - self._saved_gain_config.write(open(self.config_filename, 'w')) - self.usrp_source.set_gain(self.gain) - - def set_freq(self, freq): - self.freq = freq - self._freq_text_box.set_value(self.freq) - self._saved_freq_config = ConfigParser.ConfigParser() - self._saved_freq_config.read(self.config_filename) - if not self._saved_freq_config.has_section('usrp'): - self._saved_freq_config.add_section('usrp') - self._saved_freq_config.set('usrp', 'freq', str(self.freq)) - self._saved_freq_config.write(open(self.config_filename, 'w')) - self.usrp_source.set_frequency(self.freq) - - def set_decim_text(self, decim_text): - self.decim_text = decim_text - self._decim_text_static_text.set_value(self.decim_text) - -if __name__ == '__main__': - parser = OptionParser(option_class=eng_option, usage="%prog: [options]") - (options, args) = parser.parse_args() - if gr.enable_realtime_scheduling() != gr.RT_OK: - print "Error: failed to enable realtime scheduling." - tb = usrp_rx_hrpt2() - tb.Run(True) - diff --git a/gr-noaa/apps/usrp_rx_hrpt_nogui.grc b/gr-noaa/apps/usrp_rx_hrpt_nogui.grc index fadc2d1d..918a954b 100644 --- a/gr-noaa/apps/usrp_rx_hrpt_nogui.grc +++ b/gr-noaa/apps/usrp_rx_hrpt_nogui.grc @@ -1,6 +1,6 @@ - Sun Sep 27 10:13:25 2009 + Sun Nov 1 19:32:32 2009 options @@ -13,7 +13,7 @@ title - USRP HRPT Receiver + author @@ -35,6 +35,10 @@ category Custom + + run_options + prompt + run True @@ -171,7 +175,7 @@ variable id - max_sync_offset + max_clock_offset _enabled @@ -179,7 +183,7 @@ value - 0.01 + 0.1 _coordinate @@ -202,11 +206,11 @@ value - 'usrp_rx_hrpt.cfg' + os.environ['HOME']+'/.gnuradio/config.conf' _coordinate - (12, 167) + (13, 162) _rotation @@ -225,11 +229,11 @@ import - import math + import math, os _coordinate - (11, 112) + (11, 109) _rotation @@ -240,7 +244,7 @@ variable_config id - output_filename + clock_alpha _enabled @@ -248,11 +252,11 @@ value - 'frames.dat' + 0.05 type - string + real config_file @@ -260,19 +264,19 @@ section - 'output' + 'usrp_rx_hrpt' option - 'filename' + 'clock_alpha' writeback - output_filename + clock_alpha _coordinate - (1146, 122) + (986, 101) _rotation @@ -283,7 +287,7 @@ variable_config id - sync_alpha + gain _enabled @@ -291,7 +295,7 @@ value - 0.05 + 35 type @@ -303,19 +307,19 @@ section - 'demod' + 'usrp_rx_hrpt' option - 'sync_alpha' + 'gain' writeback - sync_alpha + gain _coordinate - (988, 121) + (668, 101) _rotation @@ -326,7 +330,7 @@ variable_config id - pll_alpha + freq _enabled @@ -334,7 +338,7 @@ value - 0.05 + 1698e6 type @@ -346,19 +350,19 @@ section - 'demod' + 'usrp_rx_hrpt' option - 'pll_alpha' + 'freq' writeback - pll_alpha + freq _coordinate - (830, 121) + (511, 100) _rotation @@ -369,7 +373,7 @@ variable_config id - gain + decim _enabled @@ -377,7 +381,7 @@ value - 35 + 16 type @@ -389,19 +393,19 @@ section - 'usrp' + 'usrp_rx_hrpt' option - 'gain' + 'decim' writeback - gain + decim _coordinate - (671, 122) + (355, 97) _rotation @@ -412,7 +416,7 @@ variable_config id - freq + output_filename _enabled @@ -420,11 +424,11 @@ value - 1698e6 + 'frames.dat' type - real + string config_file @@ -432,19 +436,19 @@ section - 'usrp' + 'usrp_rx_hrpt' option - 'freq' + 'filename' writeback - freq + output_filename _coordinate - (514, 121) + (1143, 101) _rotation @@ -455,7 +459,7 @@ variable_config id - decim + pll_alpha _enabled @@ -463,7 +467,7 @@ value - 16 + 0.05 type @@ -475,19 +479,19 @@ section - 'usrp' + 'usrp_rx_hrpt' option - 'decim' + 'pll_alpha' writeback - decim + pll_alpha _coordinate - (358, 118) + (827, 100) _rotation @@ -518,7 +522,7 @@ section - 'usrp' + 'usrp_rx_hrpt' option @@ -530,7 +534,7 @@ _coordinate - (201, 116) + (198, 95) _rotation @@ -538,18 +542,38 @@ - noaa_hrpt_decoder + gr_agc_xx id - decoder + agc _enabled True + + type + complex + + + rate + 1e-6 + + + reference + 1.0 + + + gain + 1.0 + + + max_gain + 1.0 + _coordinate - (1247, 347) + (339, 434) _rotation @@ -608,7 +632,7 @@ _coordinate - (29, 303) + (127, 418) _rotation @@ -616,22 +640,42 @@ - variable + gr_clock_recovery_mm_xx id - mf_taps + gr_clock_recovery_mm_xx_0 _enabled True - value - [-0.5/hs,]*hs+[0.5/hs,]*hs + type + float + + + omega + sps/2.0 + + + gain_omega + clock_alpha**2/4.0 + + + mu + 0.5 + + + gain_mu + clock_alpha + + + omega_relative_limit + max_clock_offset _coordinate - (825, 19) + (920, 426) _rotation @@ -639,10 +683,10 @@ - gr_agc_xx + gr_moving_average_xx id - agc + gr_moving_average_xx_0 _enabled @@ -650,27 +694,77 @@ type - complex + float - rate - 1e-6 + length + hs - reference - 1.0 + scale + 1.0/hs - gain - 1.0 + max_iter + 4000 - max_gain - 1.0 + _coordinate + (720, 442) + + + _rotation + 0 + + + + noaa_hrpt_pll_cf + + id + pll + + + _enabled + True + + + alpha + pll_alpha + + + beta + pll_alpha**2/4.0 + + + max_offset + max_carrier_offset _coordinate - (246, 319) + (507, 442) + + + _rotation + 0 + + + + virtual_sink + + id + virtual_sink_0 + + + _enabled + True + + + stream_id + baseband + + + _coordinate + (1180, 457) _rotation @@ -689,7 +783,7 @@ _coordinate - (1060, 347) + (815, 673) _rotation @@ -720,7 +814,7 @@ _coordinate - (1251, 454) + (1026, 722) _rotation @@ -728,34 +822,37 @@ - noaa_hrpt_sync_fb + noaa_hrpt_bit_sync id - sync + noaa_hrpt_bit_sync_0 _enabled True - alpha - sync_alpha + _coordinate + (624, 673) - beta - sync_alpha**2/4.0 + _rotation + 0 + + + gr_binary_slicer_fb - sps - sps + id + gr_binary_slicer_fb_0 - max_offset - max_sync_offset + _enabled + True _coordinate - (833, 319) + (446, 673) _rotation @@ -763,30 +860,22 @@ - noaa_hrpt_pll_cf + virtual_source id - pll + virtual_source_0 _enabled True - alpha - pll_alpha - - - beta - pll_alpha**2/4.0 - - - max_offset - max_carrier_offset + stream_id + baseband _coordinate - (638, 327) + (226, 669) _rotation @@ -794,30 +883,18 @@ - gr_fir_filter_xxx + noaa_hrpt_decoder id - gr_fir_filter_xxx_0 + decoder _enabled True - - type - ccc - - - decim - 1 - - - taps - mf_taps - _coordinate - (402, 335) + (1027, 623) _rotation @@ -831,38 +908,56 @@ 0 - deframer - decoder + agc + pll 0 0 pll - sync + gr_moving_average_xx_0 + 0 + 0 + + + gr_moving_average_xx_0 + gr_clock_recovery_mm_xx_0 + 0 + 0 + + + gr_clock_recovery_mm_xx_0 + virtual_sink_0 0 0 - sync + noaa_hrpt_bit_sync_0 deframer 0 0 - deframer - frame_sink + gr_binary_slicer_fb_0 + noaa_hrpt_bit_sync_0 0 0 - agc - gr_fir_filter_xxx_0 + virtual_source_0 + gr_binary_slicer_fb_0 0 0 - gr_fir_filter_xxx_0 - pll + deframer + frame_sink + 0 + 0 + + + deframer + decoder 0 0 diff --git a/gr-noaa/apps/usrp_rx_hrpt_nogui.py b/gr-noaa/apps/usrp_rx_hrpt_nogui.py index 9917847b..33259a23 100755 --- a/gr-noaa/apps/usrp_rx_hrpt_nogui.py +++ b/gr-noaa/apps/usrp_rx_hrpt_nogui.py @@ -1,8 +1,8 @@ #!/usr/bin/env python ################################################## # Gnuradio Python Flow Graph -# Title: USRP HRPT Receiver -# Generated: Sun Sep 27 10:13:25 2009 +# Title: Usrp Rx Hrpt Nogui +# Generated: Sun Nov 1 19:32:32 2009 ################################################## from gnuradio import eng_notation @@ -13,59 +13,58 @@ from gnuradio.gr import firdes from grc_gnuradio import usrp as grc_usrp from optparse import OptionParser import ConfigParser -import math +import math, os class usrp_rx_hrpt_nogui(gr.top_block): def __init__(self): - gr.top_block.__init__(self, "USRP HRPT Receiver") + gr.top_block.__init__(self, "Usrp Rx Hrpt Nogui") ################################################## # Variables ################################################## - self.config_filename = config_filename = 'usrp_rx_hrpt.cfg' + self.config_filename = config_filename = os.environ['HOME']+'/.gnuradio/config.conf' self._decim_config = ConfigParser.ConfigParser() self._decim_config.read(config_filename) - try: decim = self._decim_config.getfloat('usrp', 'decim') + try: decim = self._decim_config.getfloat('usrp_rx_hrpt', 'decim') except: decim = 16 self.decim = decim self.sym_rate = sym_rate = 600*1109 self.sample_rate = sample_rate = 64e6/decim self.sps = sps = sample_rate/sym_rate - self.hs = hs = int(sps/2.0) - self._sync_alpha_config = ConfigParser.ConfigParser() - self._sync_alpha_config.read(config_filename) - try: sync_alpha = self._sync_alpha_config.getfloat('demod', 'sync_alpha') - except: sync_alpha = 0.05 - self.sync_alpha = sync_alpha self._side_config = ConfigParser.ConfigParser() self._side_config.read(config_filename) - try: side = self._side_config.get('usrp', 'side') + try: side = self._side_config.get('usrp_rx_hrpt', 'side') except: side = 'A' self.side = side self._pll_alpha_config = ConfigParser.ConfigParser() self._pll_alpha_config.read(config_filename) - try: pll_alpha = self._pll_alpha_config.getfloat('demod', 'pll_alpha') + try: pll_alpha = self._pll_alpha_config.getfloat('usrp_rx_hrpt', 'pll_alpha') except: pll_alpha = 0.05 self.pll_alpha = pll_alpha self._output_filename_config = ConfigParser.ConfigParser() self._output_filename_config.read(config_filename) - try: output_filename = self._output_filename_config.get('output', 'filename') + try: output_filename = self._output_filename_config.get('usrp_rx_hrpt', 'filename') except: output_filename = 'frames.dat' self.output_filename = output_filename - self.mf_taps = mf_taps = [-0.5/hs,]*hs+[0.5/hs,]*hs - self.max_sync_offset = max_sync_offset = 0.01 + self.max_clock_offset = max_clock_offset = 0.1 self.max_carrier_offset = max_carrier_offset = 2*math.pi*100e3/sample_rate + self.hs = hs = int(sps/2.0) self._gain_config = ConfigParser.ConfigParser() self._gain_config.read(config_filename) - try: gain = self._gain_config.getfloat('usrp', 'gain') + try: gain = self._gain_config.getfloat('usrp_rx_hrpt', 'gain') except: gain = 35 self.gain = gain self._freq_config = ConfigParser.ConfigParser() self._freq_config.read(config_filename) - try: freq = self._freq_config.getfloat('usrp', 'freq') + try: freq = self._freq_config.getfloat('usrp_rx_hrpt', 'freq') except: freq = 1698e6 self.freq = freq + self._clock_alpha_config = ConfigParser.ConfigParser() + self._clock_alpha_config.read(config_filename) + try: clock_alpha = self._clock_alpha_config.getfloat('usrp_rx_hrpt', 'clock_alpha') + except: clock_alpha = 0.05 + self.clock_alpha = clock_alpha ################################################## # Blocks @@ -74,9 +73,11 @@ class usrp_rx_hrpt_nogui(gr.top_block): self.decoder = noaa.hrpt_decoder() self.deframer = noaa.hrpt_deframer() self.frame_sink = gr.file_sink(gr.sizeof_short*1, output_filename) - self.gr_fir_filter_xxx_0 = gr.fir_filter_ccc(1, (mf_taps)) + self.gr_binary_slicer_fb_0 = gr.binary_slicer_fb() + self.gr_clock_recovery_mm_xx_0 = gr.clock_recovery_mm_ff(sps/2.0, clock_alpha**2/4.0, 0.5, clock_alpha, max_clock_offset) + self.gr_moving_average_xx_0 = gr.moving_average_ff(hs, 1.0/hs, 4000) + self.noaa_hrpt_bit_sync_0 = noaa.hrpt_bit_sync() self.pll = noaa.hrpt_pll_cf(pll_alpha, pll_alpha**2/4.0, max_carrier_offset) - self.sync = noaa.hrpt_sync_fb(sync_alpha, sync_alpha**2/4.0, sps, max_sync_offset) self.usrp_source = grc_usrp.simple_source_c(which=0, side=side, rx_ant="RXA") self.usrp_source.set_decim_rate(decim) self.usrp_source.set_frequency(freq, verbose=True) @@ -86,56 +87,58 @@ class usrp_rx_hrpt_nogui(gr.top_block): # Connections ################################################## self.connect((self.usrp_source, 0), (self.agc, 0)) - self.connect((self.deframer, 0), (self.decoder, 0)) - self.connect((self.pll, 0), (self.sync, 0)) - self.connect((self.sync, 0), (self.deframer, 0)) + self.connect((self.agc, 0), (self.pll, 0)) + self.connect((self.pll, 0), (self.gr_moving_average_xx_0, 0)) + self.connect((self.gr_moving_average_xx_0, 0), (self.gr_clock_recovery_mm_xx_0, 0)) + self.connect((self.noaa_hrpt_bit_sync_0, 0), (self.deframer, 0)) + self.connect((self.gr_binary_slicer_fb_0, 0), (self.noaa_hrpt_bit_sync_0, 0)) + self.connect((self.gr_clock_recovery_mm_xx_0, 0), (self.gr_binary_slicer_fb_0, 0)) self.connect((self.deframer, 0), (self.frame_sink, 0)) - self.connect((self.agc, 0), (self.gr_fir_filter_xxx_0, 0)) - self.connect((self.gr_fir_filter_xxx_0, 0), (self.pll, 0)) + self.connect((self.deframer, 0), (self.decoder, 0)) def set_config_filename(self, config_filename): self.config_filename = config_filename - self._output_filename_config = ConfigParser.ConfigParser() - self._output_filename_config.read(self.config_filename) - if not self._output_filename_config.has_section('output'): - self._output_filename_config.add_section('output') - self._output_filename_config.set('output', 'filename', str(self.output_filename)) - self._output_filename_config.write(open(self.config_filename, 'w')) - self._sync_alpha_config = ConfigParser.ConfigParser() - self._sync_alpha_config.read(self.config_filename) - if not self._sync_alpha_config.has_section('demod'): - self._sync_alpha_config.add_section('demod') - self._sync_alpha_config.set('demod', 'sync_alpha', str(self.sync_alpha)) - self._sync_alpha_config.write(open(self.config_filename, 'w')) - self._pll_alpha_config = ConfigParser.ConfigParser() - self._pll_alpha_config.read(self.config_filename) - if not self._pll_alpha_config.has_section('demod'): - self._pll_alpha_config.add_section('demod') - self._pll_alpha_config.set('demod', 'pll_alpha', str(self.pll_alpha)) - self._pll_alpha_config.write(open(self.config_filename, 'w')) + self._clock_alpha_config = ConfigParser.ConfigParser() + self._clock_alpha_config.read(self.config_filename) + if not self._clock_alpha_config.has_section('usrp_rx_hrpt'): + self._clock_alpha_config.add_section('usrp_rx_hrpt') + self._clock_alpha_config.set('usrp_rx_hrpt', 'clock_alpha', str(self.clock_alpha)) + self._clock_alpha_config.write(open(self.config_filename, 'w')) self._gain_config = ConfigParser.ConfigParser() self._gain_config.read(self.config_filename) - if not self._gain_config.has_section('usrp'): - self._gain_config.add_section('usrp') - self._gain_config.set('usrp', 'gain', str(self.gain)) + if not self._gain_config.has_section('usrp_rx_hrpt'): + self._gain_config.add_section('usrp_rx_hrpt') + self._gain_config.set('usrp_rx_hrpt', 'gain', str(self.gain)) self._gain_config.write(open(self.config_filename, 'w')) self._freq_config = ConfigParser.ConfigParser() self._freq_config.read(self.config_filename) - if not self._freq_config.has_section('usrp'): - self._freq_config.add_section('usrp') - self._freq_config.set('usrp', 'freq', str(self.freq)) + if not self._freq_config.has_section('usrp_rx_hrpt'): + self._freq_config.add_section('usrp_rx_hrpt') + self._freq_config.set('usrp_rx_hrpt', 'freq', str(self.freq)) self._freq_config.write(open(self.config_filename, 'w')) self._decim_config = ConfigParser.ConfigParser() self._decim_config.read(self.config_filename) - if not self._decim_config.has_section('usrp'): - self._decim_config.add_section('usrp') - self._decim_config.set('usrp', 'decim', str(self.decim)) + if not self._decim_config.has_section('usrp_rx_hrpt'): + self._decim_config.add_section('usrp_rx_hrpt') + self._decim_config.set('usrp_rx_hrpt', 'decim', str(self.decim)) self._decim_config.write(open(self.config_filename, 'w')) + self._output_filename_config = ConfigParser.ConfigParser() + self._output_filename_config.read(self.config_filename) + if not self._output_filename_config.has_section('usrp_rx_hrpt'): + self._output_filename_config.add_section('usrp_rx_hrpt') + self._output_filename_config.set('usrp_rx_hrpt', 'filename', str(self.output_filename)) + self._output_filename_config.write(open(self.config_filename, 'w')) + self._pll_alpha_config = ConfigParser.ConfigParser() + self._pll_alpha_config.read(self.config_filename) + if not self._pll_alpha_config.has_section('usrp_rx_hrpt'): + self._pll_alpha_config.add_section('usrp_rx_hrpt') + self._pll_alpha_config.set('usrp_rx_hrpt', 'pll_alpha', str(self.pll_alpha)) + self._pll_alpha_config.write(open(self.config_filename, 'w')) self._side_config = ConfigParser.ConfigParser() self._side_config.read(self.config_filename) - if not self._side_config.has_section('usrp'): - self._side_config.add_section('usrp') - self._side_config.set('usrp', 'side', str(self.side)) + if not self._side_config.has_section('usrp_rx_hrpt'): + self._side_config.add_section('usrp_rx_hrpt') + self._side_config.set('usrp_rx_hrpt', 'side', str(self.side)) self._side_config.write(open(self.config_filename, 'w')) def set_decim(self, decim): @@ -143,9 +146,9 @@ class usrp_rx_hrpt_nogui(gr.top_block): self.set_sample_rate(64e6/self.decim) self._decim_config = ConfigParser.ConfigParser() self._decim_config.read(self.config_filename) - if not self._decim_config.has_section('usrp'): - self._decim_config.add_section('usrp') - self._decim_config.set('usrp', 'decim', str(self.decim)) + if not self._decim_config.has_section('usrp_rx_hrpt'): + self._decim_config.add_section('usrp_rx_hrpt') + self._decim_config.set('usrp_rx_hrpt', 'decim', str(self.decim)) self._decim_config.write(open(self.config_filename, 'w')) self.usrp_source.set_decim_rate(self.decim) @@ -161,38 +164,24 @@ class usrp_rx_hrpt_nogui(gr.top_block): def set_sps(self, sps): self.sps = sps self.set_hs(int(self.sps/2.0)) - - def set_hs(self, hs): - self.hs = hs - self.set_mf_taps([-0.5/self.hs,]*self.hs+[0.5/self.hs,]*self.hs) - - def set_sync_alpha(self, sync_alpha): - self.sync_alpha = sync_alpha - self._sync_alpha_config = ConfigParser.ConfigParser() - self._sync_alpha_config.read(self.config_filename) - if not self._sync_alpha_config.has_section('demod'): - self._sync_alpha_config.add_section('demod') - self._sync_alpha_config.set('demod', 'sync_alpha', str(self.sync_alpha)) - self._sync_alpha_config.write(open(self.config_filename, 'w')) - self.sync.set_alpha(self.sync_alpha) - self.sync.set_beta(self.sync_alpha**2/4.0) + self.gr_clock_recovery_mm_xx_0.set_omega(self.sps/2.0) def set_side(self, side): self.side = side self._side_config = ConfigParser.ConfigParser() self._side_config.read(self.config_filename) - if not self._side_config.has_section('usrp'): - self._side_config.add_section('usrp') - self._side_config.set('usrp', 'side', str(self.side)) + if not self._side_config.has_section('usrp_rx_hrpt'): + self._side_config.add_section('usrp_rx_hrpt') + self._side_config.set('usrp_rx_hrpt', 'side', str(self.side)) self._side_config.write(open(self.config_filename, 'w')) def set_pll_alpha(self, pll_alpha): self.pll_alpha = pll_alpha self._pll_alpha_config = ConfigParser.ConfigParser() self._pll_alpha_config.read(self.config_filename) - if not self._pll_alpha_config.has_section('demod'): - self._pll_alpha_config.add_section('demod') - self._pll_alpha_config.set('demod', 'pll_alpha', str(self.pll_alpha)) + if not self._pll_alpha_config.has_section('usrp_rx_hrpt'): + self._pll_alpha_config.add_section('usrp_rx_hrpt') + self._pll_alpha_config.set('usrp_rx_hrpt', 'pll_alpha', str(self.pll_alpha)) self._pll_alpha_config.write(open(self.config_filename, 'w')) self.pll.set_alpha(self.pll_alpha) self.pll.set_beta(self.pll_alpha**2/4.0) @@ -201,30 +190,29 @@ class usrp_rx_hrpt_nogui(gr.top_block): self.output_filename = output_filename self._output_filename_config = ConfigParser.ConfigParser() self._output_filename_config.read(self.config_filename) - if not self._output_filename_config.has_section('output'): - self._output_filename_config.add_section('output') - self._output_filename_config.set('output', 'filename', str(self.output_filename)) + if not self._output_filename_config.has_section('usrp_rx_hrpt'): + self._output_filename_config.add_section('usrp_rx_hrpt') + self._output_filename_config.set('usrp_rx_hrpt', 'filename', str(self.output_filename)) self._output_filename_config.write(open(self.config_filename, 'w')) - def set_mf_taps(self, mf_taps): - self.mf_taps = mf_taps - self.gr_fir_filter_xxx_0.set_taps((self.mf_taps)) - - def set_max_sync_offset(self, max_sync_offset): - self.max_sync_offset = max_sync_offset - self.sync.set_max_offset(self.max_sync_offset) + def set_max_clock_offset(self, max_clock_offset): + self.max_clock_offset = max_clock_offset def set_max_carrier_offset(self, max_carrier_offset): self.max_carrier_offset = max_carrier_offset self.pll.set_max_offset(self.max_carrier_offset) + def set_hs(self, hs): + self.hs = hs + self.gr_moving_average_xx_0.set_length_and_scale(self.hs, 1.0/self.hs) + def set_gain(self, gain): self.gain = gain self._gain_config = ConfigParser.ConfigParser() self._gain_config.read(self.config_filename) - if not self._gain_config.has_section('usrp'): - self._gain_config.add_section('usrp') - self._gain_config.set('usrp', 'gain', str(self.gain)) + if not self._gain_config.has_section('usrp_rx_hrpt'): + self._gain_config.add_section('usrp_rx_hrpt') + self._gain_config.set('usrp_rx_hrpt', 'gain', str(self.gain)) self._gain_config.write(open(self.config_filename, 'w')) self.usrp_source.set_gain(self.gain) @@ -232,12 +220,23 @@ class usrp_rx_hrpt_nogui(gr.top_block): self.freq = freq self._freq_config = ConfigParser.ConfigParser() self._freq_config.read(self.config_filename) - if not self._freq_config.has_section('usrp'): - self._freq_config.add_section('usrp') - self._freq_config.set('usrp', 'freq', str(self.freq)) + if not self._freq_config.has_section('usrp_rx_hrpt'): + self._freq_config.add_section('usrp_rx_hrpt') + self._freq_config.set('usrp_rx_hrpt', 'freq', str(self.freq)) self._freq_config.write(open(self.config_filename, 'w')) self.usrp_source.set_frequency(self.freq) + def set_clock_alpha(self, clock_alpha): + self.clock_alpha = clock_alpha + self._clock_alpha_config = ConfigParser.ConfigParser() + self._clock_alpha_config.read(self.config_filename) + if not self._clock_alpha_config.has_section('usrp_rx_hrpt'): + self._clock_alpha_config.add_section('usrp_rx_hrpt') + self._clock_alpha_config.set('usrp_rx_hrpt', 'clock_alpha', str(self.clock_alpha)) + self._clock_alpha_config.write(open(self.config_filename, 'w')) + self.gr_clock_recovery_mm_xx_0.set_gain_omega(self.clock_alpha**2/4.0) + self.gr_clock_recovery_mm_xx_0.set_gain_mu(self.clock_alpha) + if __name__ == '__main__': parser = OptionParser(option_class=eng_option, usage="%prog: [options]") (options, args) = parser.parse_args() diff --git a/gr-noaa/grc/Makefile.am b/gr-noaa/grc/Makefile.am index a290204b..800d9ad6 100644 --- a/gr-noaa/grc/Makefile.am +++ b/gr-noaa/grc/Makefile.am @@ -24,8 +24,8 @@ include $(top_srcdir)/Makefile.common grcblocksdir = $(grc_blocksdir) dist_grcblocks_DATA = \ + noaa_hrpt_bit_sync.xml \ noaa_hrpt_decoder.xml \ noaa_hrpt_deframer.xml \ - noaa_hrpt_pll_cf.xml \ - noaa_hrpt_sync_fb.xml + noaa_hrpt_pll_cf.xml diff --git a/gr-noaa/grc/noaa_hrpt_bit_sync.xml b/gr-noaa/grc/noaa_hrpt_bit_sync.xml new file mode 100644 index 00000000..7dcb8274 --- /dev/null +++ b/gr-noaa/grc/noaa_hrpt_bit_sync.xml @@ -0,0 +1,16 @@ + + + HRPT Bit Sync + noaa_hrpt_bit_sync + NOAA + from gnuradio import noaa + noaa.hrpt_bit_sync() + + in + byte + + + out + byte + + diff --git a/gr-noaa/grc/noaa_hrpt_sync_fb.xml b/gr-noaa/grc/noaa_hrpt_sync_fb.xml deleted file mode 100644 index e066e348..00000000 --- a/gr-noaa/grc/noaa_hrpt_sync_fb.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - HRPT SYNC - noaa_hrpt_sync_fb - NOAA - from gnuradio import noaa - noaa.hrpt_sync_fb($alpha, $beta, $sps, $max_offset) - set_alpha($alpha) - set_beta($beta) - set_max_offset($max_offset) - - Alpha - alpha - real - - - Beta - beta - real - - - Samples/Symbol - sps - real - - - Max Offset - max_offset - real - - - in - float - - - out - byte - - diff --git a/gr-noaa/lib/Makefile.am b/gr-noaa/lib/Makefile.am index 6435d192..a4423167 100644 --- a/gr-noaa/lib/Makefile.am +++ b/gr-noaa/lib/Makefile.am @@ -29,10 +29,10 @@ lib_LTLIBRARIES = \ libgnuradio-noaa.la libgnuradio_noaa_la_SOURCES = \ + noaa_hrpt_bit_sync.cc \ noaa_hrpt_decoder.cc \ noaa_hrpt_deframer.cc \ - noaa_hrpt_pll_cf.cc \ - noaa_hrpt_sync_fb.cc + noaa_hrpt_pll_cf.cc libgnuradio_noaa_la_LIBADD = \ $(GNURADIO_CORE_LA) @@ -40,7 +40,7 @@ libgnuradio_noaa_la_LIBADD = \ libgnuradio_noaa_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0 grinclude_HEADERS = \ + noaa_hrpt_bit_sync.h \ noaa_hrpt_decoder.h \ noaa_hrpt_deframer.h \ - noaa_hrpt_pll_cf.h \ - noaa_hrpt_sync_fb.h + noaa_hrpt_pll_cf.h \ No newline at end of file diff --git a/gr-noaa/lib/noaa_hrpt_bit_sync.cc b/gr-noaa/lib/noaa_hrpt_bit_sync.cc new file mode 100644 index 00000000..53e47d91 --- /dev/null +++ b/gr-noaa/lib/noaa_hrpt_bit_sync.cc @@ -0,0 +1,72 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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. + * + * GNU Radio 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 GNU Radio; 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 +#include +#include + +noaa_hrpt_bit_sync_sptr +noaa_make_hrpt_bit_sync() +{ + return gnuradio::get_initial_sptr(new noaa_hrpt_bit_sync()); +} + +noaa_hrpt_bit_sync::noaa_hrpt_bit_sync() + : gr_block("noaa_hrpt_bit_sync", + gr_make_io_signature(1, 1, sizeof(char)), + gr_make_io_signature(1, 1, sizeof(char))), + d_mid_bit(true), + d_last_bit(0) +{ +} + +int +noaa_hrpt_bit_sync::general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + int ninputs = ninput_items[0]; + const char *in = (const char *)input_items[0]; + char *out = (char *)output_items[0]; + + int i = 0, j = 0; + while (i < ninputs && j < noutput_items) { + char bit = in[i++]; + char diff = bit^d_last_bit; + d_last_bit = bit; + + if (d_mid_bit && diff) { + out[j++] = bit; + d_mid_bit = false; + } + else + d_mid_bit = true; + } + + consume_each(i); + return j; +} diff --git a/gr-noaa/lib/noaa_hrpt_bit_sync.h b/gr-noaa/lib/noaa_hrpt_bit_sync.h new file mode 100644 index 00000000..8b8633cd --- /dev/null +++ b/gr-noaa/lib/noaa_hrpt_bit_sync.h @@ -0,0 +1,49 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_NOAA_HRPT_BIT_SYNC_H +#define INCLUDED_NOAA_HRPT_BIT_SYNC_H + +#include + +class noaa_hrpt_bit_sync; +typedef boost::shared_ptr noaa_hrpt_bit_sync_sptr; + +noaa_hrpt_bit_sync_sptr +noaa_make_hrpt_bit_sync(); + +class noaa_hrpt_bit_sync : public gr_block +{ + friend noaa_hrpt_bit_sync_sptr noaa_make_hrpt_bit_sync(); + noaa_hrpt_bit_sync(); + + bool d_mid_bit; + unsigned char d_last_bit; + + public: + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif /* INCLUDED_NOAA_HRPT_BIT_SYNC_H */ diff --git a/gr-noaa/lib/noaa_hrpt_sync_fb.cc b/gr-noaa/lib/noaa_hrpt_sync_fb.cc deleted file mode 100644 index 9c655b0d..00000000 --- a/gr-noaa/lib/noaa_hrpt_sync_fb.cc +++ /dev/null @@ -1,95 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2009 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; 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 -#include - -inline int signum(float f) -{ - return f >= 0.0 ? 1 : -1; -} - -noaa_hrpt_sync_fb_sptr -noaa_make_hrpt_sync_fb(float alpha, float beta, float sps, float max_offset) -{ - return gnuradio::get_initial_sptr(new noaa_hrpt_sync_fb(alpha, beta, sps, max_offset)); -} - -noaa_hrpt_sync_fb::noaa_hrpt_sync_fb(float alpha, float beta, float sps, float max_offset) - : gr_block("noaa_hrpt_sync_fb", - gr_make_io_signature(1, 1, sizeof(float)), - gr_make_io_signature(1, 1, sizeof(char))), - d_alpha(alpha), d_beta(beta), - d_sps(sps), d_max_offset(max_offset), - d_phase(0.0), d_freq(1.0/sps), - d_last_sign(1) -{ -} - -int -noaa_hrpt_sync_fb::general_work(int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - int ninputs = ninput_items[0]; - const float *in = (const float *)input_items[0]; - char *out = (char *)output_items[0]; - - int i = 0, j = 0; - while (i < ninputs && j < noutput_items) { - float sample = in[i++]; - int sign = signum(sample); - d_phase += d_freq; - - // Train on zero crossings in center region of symbol - if (sign != d_last_sign) { - float phase_err = 0.0; - if (d_phase > 0.25 && d_phase < 0.75) - phase_err = d_phase-0.5; - else if (d_phase >= 0.75) - phase_err = d_phase - 1.0; - else - phase_err = d_phase; - - d_phase -= phase_err*d_alpha; // 1st order phase adjustment - d_freq -= phase_err*d_beta; // 2nd order frequency adjustment - - d_last_sign = sign; - } - - if (d_phase > 1.0) { - if (sample < 0.0) - out[j++] = 1; - else - out[j++] = 0; - d_phase -= 1.0; - } - } - - consume_each(i); - return j; -} diff --git a/gr-noaa/lib/noaa_hrpt_sync_fb.h b/gr-noaa/lib/noaa_hrpt_sync_fb.h deleted file mode 100644 index a9416b9e..00000000 --- a/gr-noaa/lib/noaa_hrpt_sync_fb.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2009 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_NOAA_HRPT_SYNC_FB_H -#define INCLUDED_NOAA_HRPT_SYNC_FB_H - -#include - -class noaa_hrpt_sync_fb; -typedef boost::shared_ptr noaa_hrpt_sync_fb_sptr; - -noaa_hrpt_sync_fb_sptr -noaa_make_hrpt_sync_fb(float alpha, float beta, float sps, float max_offset); - -class noaa_hrpt_sync_fb : public gr_block -{ - friend noaa_hrpt_sync_fb_sptr noaa_make_hrpt_sync_fb(float alpha, float beta, float sps, float max_offset); - noaa_hrpt_sync_fb(float alpha, float beta, float sps, float max_offset); - - float d_alpha; // 1st order loop constant - float d_beta; // 2nd order loop constant - float d_sps; // samples per symbol - float d_max_offset; // Maximum frequency offset for d_sps, samples/symbol - float d_phase; // Instantaneous symbol phase - float d_freq; // Instantaneous symbol frequency, samples/symbol - int d_last_sign; // Tracks zero crossings - - public: - int general_work(int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - - void set_alpha(float alpha) { d_alpha = alpha; } - void set_beta(float beta) { d_beta = beta; } - void set_max_offset(float max_offset) { d_max_offset = max_offset; } -}; - -#endif /* INCLUDED_NOAA_HRPT_SYNC_FB_H */ diff --git a/gr-noaa/swig/Makefile.am b/gr-noaa/swig/Makefile.am index 3ac7879d..97056811 100644 --- a/gr-noaa/swig/Makefile.am +++ b/gr-noaa/swig/Makefile.am @@ -52,10 +52,10 @@ noaa_swig_python = \ # additional SWIG files to be installed noaa_swig_swiginclude_headers = \ + noaa_hrpt_bit_sync.i \ noaa_hrpt_decoder.i \ noaa_hrpt_deframer.i \ - noaa_hrpt_pll_cf.i \ - noaa_hrpt_sync_fb.i + noaa_hrpt_pll_cf.i include $(top_srcdir)/Makefile.swig diff --git a/gr-noaa/swig/noaa_hrpt_sync_fb.i b/gr-noaa/swig/noaa_hrpt_bit_sync.i similarity index 72% rename from gr-noaa/swig/noaa_hrpt_sync_fb.i rename to gr-noaa/swig/noaa_hrpt_bit_sync.i index a8e5b21d..34b565c2 100644 --- a/gr-noaa/swig/noaa_hrpt_sync_fb.i +++ b/gr-noaa/swig/noaa_hrpt_bit_sync.i @@ -20,18 +20,13 @@ * Boston, MA 02110-1301, USA. */ -GR_SWIG_BLOCK_MAGIC(noaa,hrpt_sync_fb) +GR_SWIG_BLOCK_MAGIC(noaa,hrpt_bit_sync) -noaa_hrpt_sync_fb_sptr -noaa_make_hrpt_sync_fb(float alpha, float beta, float sps, float max_offset); +noaa_hrpt_bit_sync_sptr +noaa_make_hrpt_bit_sync(); -class noaa_hrpt_sync_fb : public gr_sync_block +class noaa_hrpt_bit_sync : public gr_sync_block { private: - noaa_hrpt_sync_fb(); - -public: - void set_alpha(float alpha); - void set_beta(float beta); - void set_max_offset(float min_freq); + noaa_hrpt_bit_sync(); }; diff --git a/gr-noaa/swig/noaa_swig.i b/gr-noaa/swig/noaa_swig.i index e6497bc4..efda4f40 100644 --- a/gr-noaa/swig/noaa_swig.i +++ b/gr-noaa/swig/noaa_swig.i @@ -23,13 +23,14 @@ %include "gnuradio.i" %{ +#include #include #include #include -#include %} +%include "noaa_hrpt_bit_sync.i" %include "noaa_hrpt_decoder.i" %include "noaa_hrpt_deframer.i" %include "noaa_hrpt_pll_cf.i" -%include "noaa_hrpt_sync_fb.i" + -- 2.30.2