a5f9a8e946148febdbca5407b72e0b754cd39e14
[debian/gnuradio] / gr-noaa / apps / usrp_rx_hrpt.py
1 #!/usr/bin/env python
2 ##################################################
3 # Gnuradio Python Flow Graph
4 # Title: USRP HRPT Receiver
5 # Generated: Mon Nov  2 08:31:10 2009
6 ##################################################
7
8 from gnuradio import eng_notation
9 from gnuradio import gr
10 from gnuradio import noaa
11 from gnuradio import window
12 from gnuradio.eng_option import eng_option
13 from gnuradio.gr import firdes
14 from gnuradio.wxgui import fftsink2
15 from gnuradio.wxgui import forms
16 from gnuradio.wxgui import scopesink2
17 from grc_gnuradio import usrp as grc_usrp
18 from grc_gnuradio import wxgui as grc_wxgui
19 from optparse import OptionParser
20 import ConfigParser
21 import math, os
22 import wx
23
24 class usrp_rx_hrpt(grc_wxgui.top_block_gui):
25
26         def __init__(self):
27                 grc_wxgui.top_block_gui.__init__(self, title="USRP HRPT Receiver")
28
29                 ##################################################
30                 # Variables
31                 ##################################################
32                 self.config_filename = config_filename = os.environ['HOME']+'/.gnuradio/config.conf'
33                 self._decim_config = ConfigParser.ConfigParser()
34                 self._decim_config.read(config_filename)
35                 try: decim = self._decim_config.getfloat('usrp_rx_hrpt', 'decim')
36                 except: decim = 16
37                 self.decim = decim
38                 self.sym_rate = sym_rate = 600*1109
39                 self.sample_rate = sample_rate = 64e6/decim
40                 self.sps = sps = sample_rate/sym_rate
41                 self._side_config = ConfigParser.ConfigParser()
42                 self._side_config.read(config_filename)
43                 try: side = self._side_config.get('usrp_rx_hrpt', 'side')
44                 except: side = 'A'
45                 self.side = side
46                 self._saved_pll_alpha_config = ConfigParser.ConfigParser()
47                 self._saved_pll_alpha_config.read(config_filename)
48                 try: saved_pll_alpha = self._saved_pll_alpha_config.getfloat('usrp_rx_hrpt', 'pll_alpha')
49                 except: saved_pll_alpha = 0.05
50                 self.saved_pll_alpha = saved_pll_alpha
51                 self._saved_gain_config = ConfigParser.ConfigParser()
52                 self._saved_gain_config.read(config_filename)
53                 try: saved_gain = self._saved_gain_config.getfloat('usrp_rx_hrpt', 'gain')
54                 except: saved_gain = 35
55                 self.saved_gain = saved_gain
56                 self._saved_freq_config = ConfigParser.ConfigParser()
57                 self._saved_freq_config.read(config_filename)
58                 try: saved_freq = self._saved_freq_config.getfloat('usrp_rx_hrpt', 'freq')
59                 except: saved_freq = 1698e6
60                 self.saved_freq = saved_freq
61                 self._saved_clock_alpha_config = ConfigParser.ConfigParser()
62                 self._saved_clock_alpha_config.read(config_filename)
63                 try: saved_clock_alpha = self._saved_clock_alpha_config.getfloat('usrp_rx_hrpt', 'clock_alpha')
64                 except: saved_clock_alpha = 0.05
65                 self.saved_clock_alpha = saved_clock_alpha
66                 self.side_text = side_text = side
67                 self.pll_alpha = pll_alpha = saved_pll_alpha
68                 self._output_filename_config = ConfigParser.ConfigParser()
69                 self._output_filename_config.read(config_filename)
70                 try: output_filename = self._output_filename_config.get('usrp_rx_hrpt', 'filename')
71                 except: output_filename = 'frames.dat'
72                 self.output_filename = output_filename
73                 self.max_clock_offset = max_clock_offset = 0.1
74                 self.max_carrier_offset = max_carrier_offset = 2*math.pi*100e3/sample_rate
75                 self.hs = hs = int(sps/2.0)
76                 self.gain = gain = saved_gain
77                 self.freq = freq = saved_freq
78                 self.decim_text = decim_text = decim
79                 self.clock_alpha = clock_alpha = saved_clock_alpha
80
81                 ##################################################
82                 # Notebooks
83                 ##################################################
84                 self.displays = wx.Notebook(self.GetWin(), style=wx.NB_TOP)
85                 self.displays.AddPage(grc_wxgui.Panel(self.displays), "Spectrum")
86                 self.displays.AddPage(grc_wxgui.Panel(self.displays), "Demod")
87                 self.GridAdd(self.displays, 2, 0, 1, 4)
88
89                 ##################################################
90                 # Controls
91                 ##################################################
92                 self._side_text_static_text = forms.static_text(
93                         parent=self.GetWin(),
94                         value=self.side_text,
95                         callback=self.set_side_text,
96                         label="USRP Side",
97                         converter=forms.str_converter(),
98                 )
99                 self.GridAdd(self._side_text_static_text, 1, 0, 1, 1)
100                 _pll_alpha_sizer = wx.BoxSizer(wx.VERTICAL)
101                 self._pll_alpha_text_box = forms.text_box(
102                         parent=self.GetWin(),
103                         sizer=_pll_alpha_sizer,
104                         value=self.pll_alpha,
105                         callback=self.set_pll_alpha,
106                         label="PLL Alpha",
107                         converter=forms.float_converter(),
108                         proportion=0,
109                 )
110                 self._pll_alpha_slider = forms.slider(
111                         parent=self.GetWin(),
112                         sizer=_pll_alpha_sizer,
113                         value=self.pll_alpha,
114                         callback=self.set_pll_alpha,
115                         minimum=0.0,
116                         maximum=0.5,
117                         num_steps=100,
118                         style=wx.SL_HORIZONTAL,
119                         cast=float,
120                         proportion=1,
121                 )
122                 self.GridAdd(_pll_alpha_sizer, 0, 2, 1, 1)
123                 _gain_sizer = wx.BoxSizer(wx.VERTICAL)
124                 self._gain_text_box = forms.text_box(
125                         parent=self.GetWin(),
126                         sizer=_gain_sizer,
127                         value=self.gain,
128                         callback=self.set_gain,
129                         label="RX Gain",
130                         converter=forms.float_converter(),
131                         proportion=0,
132                 )
133                 self._gain_slider = forms.slider(
134                         parent=self.GetWin(),
135                         sizer=_gain_sizer,
136                         value=self.gain,
137                         callback=self.set_gain,
138                         minimum=0,
139                         maximum=100,
140                         num_steps=100,
141                         style=wx.SL_HORIZONTAL,
142                         cast=float,
143                         proportion=1,
144                 )
145                 self.GridAdd(_gain_sizer, 0, 1, 1, 1)
146                 self._freq_text_box = forms.text_box(
147                         parent=self.GetWin(),
148                         value=self.freq,
149                         callback=self.set_freq,
150                         label="Frequency",
151                         converter=forms.float_converter(),
152                 )
153                 self.GridAdd(self._freq_text_box, 0, 0, 1, 1)
154                 self._decim_text_static_text = forms.static_text(
155                         parent=self.GetWin(),
156                         value=self.decim_text,
157                         callback=self.set_decim_text,
158                         label="Decimation",
159                         converter=forms.float_converter(),
160                 )
161                 self.GridAdd(self._decim_text_static_text, 1, 1, 1, 1)
162                 _clock_alpha_sizer = wx.BoxSizer(wx.VERTICAL)
163                 self._clock_alpha_text_box = forms.text_box(
164                         parent=self.GetWin(),
165                         sizer=_clock_alpha_sizer,
166                         value=self.clock_alpha,
167                         callback=self.set_clock_alpha,
168                         label="Clock Alpha",
169                         converter=forms.float_converter(),
170                         proportion=0,
171                 )
172                 self._clock_alpha_slider = forms.slider(
173                         parent=self.GetWin(),
174                         sizer=_clock_alpha_sizer,
175                         value=self.clock_alpha,
176                         callback=self.set_clock_alpha,
177                         minimum=0.0,
178                         maximum=0.5,
179                         num_steps=100,
180                         style=wx.SL_HORIZONTAL,
181                         cast=float,
182                         proportion=1,
183                 )
184                 self.GridAdd(_clock_alpha_sizer, 0, 3, 1, 1)
185
186                 ##################################################
187                 # Blocks
188                 ##################################################
189                 self.agc = gr.agc_cc(1e-6, 1.0, 1.0, 1.0)
190                 self.decoder = noaa.hrpt_decoder()
191                 self.deframer = noaa.hrpt_deframer()
192                 self.demod_scope = scopesink2.scope_sink_f(
193                         self.displays.GetPage(1).GetWin(),
194                         title="Post-Demod",
195                         sample_rate=sym_rate*2.0,
196                         v_scale=0.5,
197                         v_offset=0,
198                         t_scale=10.0/sym_rate,
199                         ac_couple=False,
200                         xy_mode=False,
201                         num_inputs=1,
202                 )
203                 self.displays.GetPage(1).GridAdd(self.demod_scope.win, 0, 0, 1, 1)
204                 self.frame_sink = gr.file_sink(gr.sizeof_short*1, output_filename)
205                 self.gr_binary_slicer_fb_0 = gr.binary_slicer_fb()
206                 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)
207                 self.gr_moving_average_xx_0 = gr.moving_average_ff(hs, 1.0/hs, 4000)
208                 self.pll = noaa.hrpt_pll_cf(pll_alpha, pll_alpha**2/4.0, max_carrier_offset)
209                 self.rx_fft = fftsink2.fft_sink_c(
210                         self.displays.GetPage(0).GetWin(),
211                         baseband_freq=freq,
212                         y_per_div=5,
213                         y_divs=8,
214                         ref_level=-5,
215                         ref_scale=2.0,
216                         sample_rate=sample_rate,
217                         fft_size=1024,
218                         fft_rate=15,
219                         average=True,
220                         avg_alpha=0.1,
221                         title="RX Spectrum",
222                         peak_hold=False,
223                         size=(640, 360),
224                 )
225                 self.displays.GetPage(0).GridAdd(self.rx_fft.win, 0, 0, 1, 1)
226                 self.usrp_source = grc_usrp.simple_source_c(which=0, side=side, rx_ant="RXA")
227                 self.usrp_source.set_decim_rate(decim)
228                 self.usrp_source.set_frequency(freq, verbose=True)
229                 self.usrp_source.set_gain(gain)
230
231                 ##################################################
232                 # Connections
233                 ##################################################
234                 self.connect((self.gr_clock_recovery_mm_xx_0, 0), (self.gr_binary_slicer_fb_0, 0))
235                 self.connect((self.deframer, 0), (self.frame_sink, 0))
236                 self.connect((self.deframer, 0), (self.decoder, 0))
237                 self.connect((self.gr_clock_recovery_mm_xx_0, 0), (self.demod_scope, 0))
238                 self.connect((self.gr_moving_average_xx_0, 0), (self.gr_clock_recovery_mm_xx_0, 0))
239                 self.connect((self.pll, 0), (self.gr_moving_average_xx_0, 0))
240                 self.connect((self.agc, 0), (self.pll, 0))
241                 self.connect((self.usrp_source, 0), (self.agc, 0))
242                 self.connect((self.agc, 0), (self.rx_fft, 0))
243                 self.connect((self.gr_binary_slicer_fb_0, 0), (self.deframer, 0))
244
245         def set_config_filename(self, config_filename):
246                 self.config_filename = config_filename
247                 self._saved_freq_config = ConfigParser.ConfigParser()
248                 self._saved_freq_config.read(self.config_filename)
249                 if not self._saved_freq_config.has_section('usrp_rx_hrpt'):
250                         self._saved_freq_config.add_section('usrp_rx_hrpt')
251                 self._saved_freq_config.set('usrp_rx_hrpt', 'freq', str(self.freq))
252                 self._saved_freq_config.write(open(self.config_filename, 'w'))
253                 self._saved_gain_config = ConfigParser.ConfigParser()
254                 self._saved_gain_config.read(self.config_filename)
255                 if not self._saved_gain_config.has_section('usrp_rx_hrpt'):
256                         self._saved_gain_config.add_section('usrp_rx_hrpt')
257                 self._saved_gain_config.set('usrp_rx_hrpt', 'gain', str(self.gain))
258                 self._saved_gain_config.write(open(self.config_filename, 'w'))
259                 self._output_filename_config = ConfigParser.ConfigParser()
260                 self._output_filename_config.read(self.config_filename)
261                 if not self._output_filename_config.has_section('usrp_rx_hrpt'):
262                         self._output_filename_config.add_section('usrp_rx_hrpt')
263                 self._output_filename_config.set('usrp_rx_hrpt', 'filename', str(self.output_filename))
264                 self._output_filename_config.write(open(self.config_filename, 'w'))
265                 self._saved_pll_alpha_config = ConfigParser.ConfigParser()
266                 self._saved_pll_alpha_config.read(self.config_filename)
267                 if not self._saved_pll_alpha_config.has_section('usrp_rx_hrpt'):
268                         self._saved_pll_alpha_config.add_section('usrp_rx_hrpt')
269                 self._saved_pll_alpha_config.set('usrp_rx_hrpt', 'pll_alpha', str(self.pll_alpha))
270                 self._saved_pll_alpha_config.write(open(self.config_filename, 'w'))
271                 self._saved_clock_alpha_config = ConfigParser.ConfigParser()
272                 self._saved_clock_alpha_config.read(self.config_filename)
273                 if not self._saved_clock_alpha_config.has_section('usrp_rx_hrpt'):
274                         self._saved_clock_alpha_config.add_section('usrp_rx_hrpt')
275                 self._saved_clock_alpha_config.set('usrp_rx_hrpt', 'clock_alpha', str(self.clock_alpha))
276                 self._saved_clock_alpha_config.write(open(self.config_filename, 'w'))
277                 self._decim_config = ConfigParser.ConfigParser()
278                 self._decim_config.read(self.config_filename)
279                 if not self._decim_config.has_section('usrp_rx_hrpt'):
280                         self._decim_config.add_section('usrp_rx_hrpt')
281                 self._decim_config.set('usrp_rx_hrpt', 'decim', str(self.decim))
282                 self._decim_config.write(open(self.config_filename, 'w'))
283                 self._side_config = ConfigParser.ConfigParser()
284                 self._side_config.read(self.config_filename)
285                 if not self._side_config.has_section('usrp_rx_hrpt'):
286                         self._side_config.add_section('usrp_rx_hrpt')
287                 self._side_config.set('usrp_rx_hrpt', 'side', str(self.side))
288                 self._side_config.write(open(self.config_filename, 'w'))
289
290         def set_decim(self, decim):
291                 self.decim = decim
292                 self.set_sample_rate(64e6/self.decim)
293                 self.set_decim_text(self.decim)
294                 self._decim_config = ConfigParser.ConfigParser()
295                 self._decim_config.read(self.config_filename)
296                 if not self._decim_config.has_section('usrp_rx_hrpt'):
297                         self._decim_config.add_section('usrp_rx_hrpt')
298                 self._decim_config.set('usrp_rx_hrpt', 'decim', str(self.decim))
299                 self._decim_config.write(open(self.config_filename, 'w'))
300                 self.usrp_source.set_decim_rate(self.decim)
301
302         def set_sym_rate(self, sym_rate):
303                 self.sym_rate = sym_rate
304                 self.set_sps(self.sample_rate/self.sym_rate)
305                 self.demod_scope.set_sample_rate(self.sym_rate*2.0)
306
307         def set_sample_rate(self, sample_rate):
308                 self.sample_rate = sample_rate
309                 self.set_max_carrier_offset(2*math.pi*100e3/self.sample_rate)
310                 self.set_sps(self.sample_rate/self.sym_rate)
311                 self.rx_fft.set_sample_rate(self.sample_rate)
312
313         def set_sps(self, sps):
314                 self.sps = sps
315                 self.set_hs(int(self.sps/2.0))
316                 self.gr_clock_recovery_mm_xx_0.set_omega(self.sps/2.0)
317
318         def set_side(self, side):
319                 self.side = side
320                 self.set_side_text(self.side)
321                 self._side_config = ConfigParser.ConfigParser()
322                 self._side_config.read(self.config_filename)
323                 if not self._side_config.has_section('usrp_rx_hrpt'):
324                         self._side_config.add_section('usrp_rx_hrpt')
325                 self._side_config.set('usrp_rx_hrpt', 'side', str(self.side))
326                 self._side_config.write(open(self.config_filename, 'w'))
327
328         def set_saved_pll_alpha(self, saved_pll_alpha):
329                 self.saved_pll_alpha = saved_pll_alpha
330                 self.set_pll_alpha(self.saved_pll_alpha)
331
332         def set_saved_gain(self, saved_gain):
333                 self.saved_gain = saved_gain
334                 self.set_gain(self.saved_gain)
335
336         def set_saved_freq(self, saved_freq):
337                 self.saved_freq = saved_freq
338                 self.set_freq(self.saved_freq)
339
340         def set_saved_clock_alpha(self, saved_clock_alpha):
341                 self.saved_clock_alpha = saved_clock_alpha
342                 self.set_clock_alpha(self.saved_clock_alpha)
343
344         def set_side_text(self, side_text):
345                 self.side_text = side_text
346                 self._side_text_static_text.set_value(self.side_text)
347
348         def set_pll_alpha(self, pll_alpha):
349                 self.pll_alpha = pll_alpha
350                 self._pll_alpha_slider.set_value(self.pll_alpha)
351                 self._pll_alpha_text_box.set_value(self.pll_alpha)
352                 self._saved_pll_alpha_config = ConfigParser.ConfigParser()
353                 self._saved_pll_alpha_config.read(self.config_filename)
354                 if not self._saved_pll_alpha_config.has_section('usrp_rx_hrpt'):
355                         self._saved_pll_alpha_config.add_section('usrp_rx_hrpt')
356                 self._saved_pll_alpha_config.set('usrp_rx_hrpt', 'pll_alpha', str(self.pll_alpha))
357                 self._saved_pll_alpha_config.write(open(self.config_filename, 'w'))
358                 self.pll.set_alpha(self.pll_alpha)
359                 self.pll.set_beta(self.pll_alpha**2/4.0)
360
361         def set_output_filename(self, output_filename):
362                 self.output_filename = output_filename
363                 self._output_filename_config = ConfigParser.ConfigParser()
364                 self._output_filename_config.read(self.config_filename)
365                 if not self._output_filename_config.has_section('usrp_rx_hrpt'):
366                         self._output_filename_config.add_section('usrp_rx_hrpt')
367                 self._output_filename_config.set('usrp_rx_hrpt', 'filename', str(self.output_filename))
368                 self._output_filename_config.write(open(self.config_filename, 'w'))
369
370         def set_max_clock_offset(self, max_clock_offset):
371                 self.max_clock_offset = max_clock_offset
372
373         def set_max_carrier_offset(self, max_carrier_offset):
374                 self.max_carrier_offset = max_carrier_offset
375                 self.pll.set_max_offset(self.max_carrier_offset)
376
377         def set_hs(self, hs):
378                 self.hs = hs
379                 self.gr_moving_average_xx_0.set_length_and_scale(self.hs, 1.0/self.hs)
380
381         def set_gain(self, gain):
382                 self.gain = gain
383                 self._gain_slider.set_value(self.gain)
384                 self._gain_text_box.set_value(self.gain)
385                 self._saved_gain_config = ConfigParser.ConfigParser()
386                 self._saved_gain_config.read(self.config_filename)
387                 if not self._saved_gain_config.has_section('usrp_rx_hrpt'):
388                         self._saved_gain_config.add_section('usrp_rx_hrpt')
389                 self._saved_gain_config.set('usrp_rx_hrpt', 'gain', str(self.gain))
390                 self._saved_gain_config.write(open(self.config_filename, 'w'))
391                 self.usrp_source.set_gain(self.gain)
392
393         def set_freq(self, freq):
394                 self.freq = freq
395                 self._freq_text_box.set_value(self.freq)
396                 self._saved_freq_config = ConfigParser.ConfigParser()
397                 self._saved_freq_config.read(self.config_filename)
398                 if not self._saved_freq_config.has_section('usrp_rx_hrpt'):
399                         self._saved_freq_config.add_section('usrp_rx_hrpt')
400                 self._saved_freq_config.set('usrp_rx_hrpt', 'freq', str(self.freq))
401                 self._saved_freq_config.write(open(self.config_filename, 'w'))
402                 self.usrp_source.set_frequency(self.freq)
403                 self.rx_fft.set_baseband_freq(self.freq)
404
405         def set_decim_text(self, decim_text):
406                 self.decim_text = decim_text
407                 self._decim_text_static_text.set_value(self.decim_text)
408
409         def set_clock_alpha(self, clock_alpha):
410                 self.clock_alpha = clock_alpha
411                 self._clock_alpha_slider.set_value(self.clock_alpha)
412                 self._clock_alpha_text_box.set_value(self.clock_alpha)
413                 self._saved_clock_alpha_config = ConfigParser.ConfigParser()
414                 self._saved_clock_alpha_config.read(self.config_filename)
415                 if not self._saved_clock_alpha_config.has_section('usrp_rx_hrpt'):
416                         self._saved_clock_alpha_config.add_section('usrp_rx_hrpt')
417                 self._saved_clock_alpha_config.set('usrp_rx_hrpt', 'clock_alpha', str(self.clock_alpha))
418                 self._saved_clock_alpha_config.write(open(self.config_filename, 'w'))
419                 self.gr_clock_recovery_mm_xx_0.set_gain_omega(self.clock_alpha**2/4.0)
420                 self.gr_clock_recovery_mm_xx_0.set_gain_mu(self.clock_alpha)
421
422 if __name__ == '__main__':
423         parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
424         (options, args) = parser.parse_args()
425         tb = usrp_rx_hrpt()
426         tb.Run(True)
427