commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r8932 - gnuradio/branches/features/experimental-gui


From: jcorgan
Subject: [Commit-gnuradio] r8932 - gnuradio/branches/features/experimental-gui
Date: Thu, 17 Jul 2008 18:23:07 -0600 (MDT)

Author: jcorgan
Date: 2008-07-17 18:23:04 -0600 (Thu, 17 Jul 2008)
New Revision: 8932

Added:
   gnuradio/branches/features/experimental-gui/const_controller.py
   gnuradio/branches/features/experimental-gui/const_gui.py
   gnuradio/branches/features/experimental-gui/test_const.sh
   gnuradio/branches/features/experimental-gui/usrp_const.py
Modified:
   gnuradio/branches/features/experimental-gui/const_streamer.py
   gnuradio/branches/features/experimental-gui/const_top_block.py
Log:
wip constellation application pieces

Added: gnuradio/branches/features/experimental-gui/const_controller.py
===================================================================
--- gnuradio/branches/features/experimental-gui/const_controller.py             
                (rev 0)
+++ gnuradio/branches/features/experimental-gui/const_controller.py     
2008-07-18 00:23:04 UTC (rev 8932)
@@ -0,0 +1,132 @@
+#
+# Copyright 2008 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.
+#
+
+"""!
+GNU Radio controller for const streamer.  Implements property/value abstraction
+above const_top_block.
+"""
+
+# Import the top block object.  Top blocks should be written not to know
+# anything about the controller or GUI layers
+from const_top_block import const_top_block
+
+from prop_val import prop_val_interface
+import threading
+
+"""!
+The const controller implements a property/value interface
+that controls all aspects of application operation.  It
+creates an underlying GNU Radio top block that it both
+manipulates in response to property updates and extracts
+from to update properties that external users will listen
+to.
+"""
+class const_controller(prop_val_interface, threading.Thread):
+    def __init__(self,
+                 order=2,
+                 frame_size=1024,
+                 frame_rate=30,
+                 which=0,
+                 decim=16,
+                 width_8=False,
+                 no_hb=False,
+                 subdev_spec=None,
+                 gain=None,
+                 freq=None,
+                 antenna=None,
+                bit_rate=None,
+                costas_alpha=0.1,
+                costas_max=0.05,
+                mm_alpha=0.05,
+                mm_max=0.05):
+        
+       prop_val_interface.__init__(self)
+       threading.Thread.__init__(self)
+
+        # Create the top block with the initial parameters
+       self._tb = const_top_block(order=order,
+                                  frame_size=frame_size,
+                                   frame_rate=frame_rate,
+                                   which=which,
+                                   decim=decim,
+                                   width_8=width_8,
+                                   no_hb=no_hb,
+                                   subdev_spec=subdev_spec,
+                                   gain=gain,
+                                   freq=freq,
+                                   antenna=antenna,
+                                  bit_rate=bit_rate,
+                                  costas_alpha=costas_alpha,
+                                  costas_max=costas_max,
+                                  mm_alpha=mm_alpha,
+                                  mm_max=mm_max)
+       
+       # External control interface.  These properties, when set by an external
+       # caller, result in the correct top block methods being invoked.
+       self.add_listener('decim',        self.set_decim)
+       self.add_listener('gain',         lambda x: self._tb.set_gain(x))
+       self.add_listener('freq',         lambda x: self._tb.set_freq(x))
+       self.add_listener('costas_alpha', lambda x: 
self._tb.set_costas_alpha(x))
+       self.add_listener('costas_max',   lambda x: self._tb.set_costas_max(x))
+       
+       # Set providers for application properties
+       self.set_provider('sample_rate', lambda: self._tb.sample_rate())
+       
+       # The controller is a thread.  This is not required but convenient here.
+       self.setDaemon(1)
+       self._keep_running = True
+       
+    def set_decim(self, decim):
+        """!
+        Listens to property 'decim'. Changes decimation rate and updates 
'sample_rate'
+        property (which triggers listeners on that property).
+        """
+        self._tb.set_decim(decim)
+       self['sample_rate'] = self._tb.sample_rate()
+
+    def on_init(self):
+       """
+       This method gets called by the external GUI or other code to start its
+       operation.
+       """
+       self._tb.start()
+       self.start()
+       
+    def run(self):
+       """
+       The background thread of the controller simply reads const frames from 
the 
+       top block message queue and sets the 'const' property to their string 
representation.
+       External code can add one or more listeners to this property to receive
+       notification when an const frame comes in.
+       """
+       while self._keep_running:
+           msg = self._tb.queue().delete_head()
+           self['const'] = msg.to_string()
+           
+    def on_exit(self):
+       """
+       This method gets called to shutdown the controller.  It lets the 
background
+       thread exit (not strictly necessary as Python will do so after the 
setDaemon(1)
+       call), then calls stop() and wait() on the top block.
+       """
+       self._keep_running = False 
+       self._tb.stop()
+       self._tb.wait()

Added: gnuradio/branches/features/experimental-gui/const_gui.py
===================================================================
--- gnuradio/branches/features/experimental-gui/const_gui.py                    
        (rev 0)
+++ gnuradio/branches/features/experimental-gui/const_gui.py    2008-07-18 
00:23:04 UTC (rev 8932)
@@ -0,0 +1,44 @@
+#
+# Copyright 2008 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.
+#
+
+# This requires GRC installed (temporary for demo purposes)
+from wxgui_app import wxgui_app
+from const_window import const_window
+
+"""!
+Top level graphical user interface for usrp_const application.  Right now
+just has the const window created; but will eventually have all the
+controls as well.
+"""
+
+class const_gui(wxgui_app):
+    def __init__(self, controller, title='const demo'):
+        wxgui_app.__init__(self, controller=controller, title=title)
+
+        self._win = const_window(parent=self.GetWin(),
+                                 controller=controller,
+                                 size=(600, 300),
+                                 title=title)
+       
+        self.Add(self._win)
+
+    def run(self):
+        self.Run()

Modified: gnuradio/branches/features/experimental-gui/const_streamer.py
===================================================================
--- gnuradio/branches/features/experimental-gui/const_streamer.py       
2008-07-17 23:26:40 UTC (rev 8931)
+++ gnuradio/branches/features/experimental-gui/const_streamer.py       
2008-07-18 00:23:04 UTC (rev 8932)
@@ -35,9 +35,9 @@
                  frame_size=1024,
                 frame_rate=30,
                 costas_alpha=0.1,
-                 costas_max_freq=0.05,
+                 costas_max=0.05,
                  mm_alpha=0.005,
-                 mm_max_freq=0.05):
+                 mm_max=0.05):
        """!
         Create a const_streamer.
        @param sample_rate          Incoming sample rate
@@ -46,9 +46,9 @@
         @param frame_size           Number of constellation points to plot at 
a time
         @param frame_rate           Number of frames/sec to create (default is 
30)
         @param costas_alpha         Costas loop 1st order gain constant 
(default is 0.1)
-        @param costas_max_freq      Costas loop maximum offset, rad/sample 
(default is 0.05)
+        @param costas_max           Costas loop maximum offset, rad/sample 
(default is 0.05)
         @param mm_alpha             Timing loop 1st order gain constant 
(default is 0.005)
-        @param mm_max_freq          Maximum timing offset in bits/sample 
(default is 0.05)
+        @param mm_max               Maximum timing offset in bits/sample 
(default is 0.05)
         """
         
        gr.hier_block2.__init__(self, "const_streamer",
@@ -58,11 +58,11 @@
        # Costas frequency/phase recovery loop
         # Critically damped 2nd order PLL
         costas_beta = 0.25*costas_alpha*costas_alpha
-        costas_min_freq = -costas_max_freq
+        costas_min = -costas_max
        self._costas = gr.costas_loop_cc(costas_alpha,
                                          costas_beta,
-                                         costas_max_freq,
-                                         costas_min_freq,
+                                         costas_max,
+                                         costas_min,
                                          order)
         
         # Timing recovery loop
@@ -70,11 +70,11 @@
         mm_freq = float(sample_rate)/bit_rate
        mm_beta = 0.25*mm_alpha*mm_alpha
         mu=0.5 # Center of bit
-       self._retime = gr.clock_recovery_mm_cc(mm_freq,        # omega,
-                                               mm_beta,        # gain_omega
+       self._retime = gr.clock_recovery_mm_cc(mm_freq,   # omega,
+                                               mm_beta,   # gain_omega
                                                mu,
-                                               mm_alpha,       # gain_mu,
-                                               mm_max_freq)    # omega_limit
+                                               mm_alpha,  # gain_mu,
+                                               mm_max)    # omega_limit
 
        # Scale to unity power
        self._agc = gr.agc_cc(1e-6);

Modified: gnuradio/branches/features/experimental-gui/const_top_block.py
===================================================================
--- gnuradio/branches/features/experimental-gui/const_top_block.py      
2008-07-17 23:26:40 UTC (rev 8931)
+++ gnuradio/branches/features/experimental-gui/const_top_block.py      
2008-07-18 00:23:04 UTC (rev 8932)
@@ -44,9 +44,9 @@
                 antenna=None,
                  bit_rate=None,
                 costas_alpha=0.1,
-                 costas_max_freq=0.05,
+                 costas_max=0.05,
                  mm_alpha=0.005,
-                 mm_max_freq=0.05
+                 mm_max=0.05
                  ):
        """!
         Create a const_top_block.
@@ -64,9 +64,9 @@
         @param antenna             Daughterboard RX antenna (default is 
board-default)
         @param bit_rate             Modulated bit rate/sec (default equivalent 
to 2 samples/bit)
         @param costas_alpha         Costas loop 1st order gain constant 
(default is 0.1)
-        @param costas_max_freq      Costas loop maximum offset, rad/sample 
(default is 0.05)
+        @param costas_max           Costas loop maximum offset, rad/sample 
(default is 0.05)
         @param mm_alpha             Timing loop 1st order gain constant 
(default is 0.005)
-        @param mm_max_freq          Maximum timing offset in bits/sample 
(default is 0.05)
+        @param mm_max               Maximum timing offset in bits/sample 
(default is 0.05)
         """
         
        gr.top_block.__init__(self, "const_top_block")
@@ -87,12 +87,13 @@
                                                    frame_size=frame_size,
                                                    frame_rate=frame_rate,
                                                    costas_alpha=costas_alpha,
-                                                   
costas_max_freq=costas_max_freq,
+                                                   costas_max=costas_max,
                                                    mm_alpha=mm_alpha,
-                                                   mm_max_freq=mm_max_freq)
+                                                   mm_max=mm_max)
 
-       self._sink = gr.file_sink(gr.sizeof_gr_complex*frame_size, 'const.dat')
-           
+       self._msgq = gr.msg_queue(2)
+       self._sink = gr.message_sink(gr.sizeof_gr_complex*frame_size, 
self._msgq, True)
+                   
        self.connect(self._u, self._const, self._sink)
 
     # "Setters", which are called externally to affect flowgraph operation
@@ -104,7 +105,7 @@
        
     def set_decim(self, decim):
        self._u.set_decim(decim)
-       self._fft.set_sample_rate(self._u.sample_rate())
+       self._const.set_sample_rate(self._u.sample_rate())
 
     # Getters, which are called externally to get information about the 
flowgraph
     def queue(self):
@@ -113,17 +114,3 @@
     def sample_rate(self):
         return self._u.sample_rate()
 
-# test code
-if __name__ == "__main__":
-    tb = const_top_block(order=2,
-                         decim=64,
-                         subdev_spec=(0, 0),
-                         gain=60,
-                         freq=2.215e9,
-                         bit_rate=250e3,
-                         costas_alpha=0.2,
-                         costas_max_freq=0.06,
-                         mm_alpha=0.05,
-                         mm_max_freq=0.05);
-
-    tb.run()

Added: gnuradio/branches/features/experimental-gui/test_const.sh
===================================================================
--- gnuradio/branches/features/experimental-gui/test_const.sh                   
        (rev 0)
+++ gnuradio/branches/features/experimental-gui/test_const.sh   2008-07-18 
00:23:04 UTC (rev 8932)
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+./usrp_const.py \
+    -f 2.215G \
+    -R A \
+    -d 64 \
+    -r 250e3 \
+    -g 60
+


Property changes on: gnuradio/branches/features/experimental-gui/test_const.sh
___________________________________________________________________
Name: svn:executable
   + *

Added: gnuradio/branches/features/experimental-gui/usrp_const.py
===================================================================
--- gnuradio/branches/features/experimental-gui/usrp_const.py                   
        (rev 0)
+++ gnuradio/branches/features/experimental-gui/usrp_const.py   2008-07-18 
00:23:04 UTC (rev 8932)
@@ -0,0 +1,127 @@
+#!/usr/bin/env python
+#
+# Copyright 2008 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.
+#
+
+from optparse import OptionParser
+from gnuradio.eng_option import eng_option
+import sys
+
+# Import the controller object
+from const_controller import const_controller
+
+# Import the GUI object
+from const_gui import const_gui
+
+def get_options():
+    parser = OptionParser(option_class=eng_option)
+    parser.add_option("-w", "--which", type="int", default=0,
+                      help="select which USRP (0, 1, ...) default is %default",
+                      metavar="NUM")
+    parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+                      help="select USRP Rx side A or B (default=first one with 
a daughterboard)")
+    parser.add_option("-A", "--antenna", default=None,
+                      help="select Rx Antenna (only on RFX-series boards)")
+    parser.add_option("-d", "--decim", type="int", default=16,
+                      help="set fgpa decimation rate to DECIM 
[default=%default]")
+    parser.add_option("-f", "--freq", type="eng_float", default=None,
+                      help="set frequency to FREQ", metavar="FREQ")
+    parser.add_option("-g", "--gain", type="eng_float", default=None,
+                      help="set gain in dB (default is midpoint)")
+    parser.add_option("-8", "--width-8", action="store_true", default=False,
+                      help="Enable 8-bit samples across USB")
+    parser.add_option("--no-hb", action="store_true", default=False,
+                       help="don't use halfband filter in usrp")
+    parser.add_option("-m", "--modulation", type="choice", 
choices=['bpsk','qpsk'], default='bpsk',
+                     help="Select modulation from 'bpsk', 'qpsk', default is 
'bpsk'")
+    parser.add_option("-r", "--rate", type="eng_float", default=500e3,
+                      help="Select modulation bit rate [default=%default]")
+    parser.add_option("", "--costas-alpha", type="eng_float", default=0.1,
+                      help="Select Costas loop first order gain, 
[default=%%default]")
+    parser.add_option("", "--costas-max", type="eng_float", default=0.05,
+                      help="Select Costas loop max offset in radians/sample, 
[default=%default]")
+    parser.add_option("", "--mm-alpha", type="eng_float", default=0.05,
+                      help="Select timing recovery loop first order gain, 
[default=%default]")
+    parser.add_option("", "--mm-max", type="eng_float", default=0.05,
+                      help="Select timing recovery loop max offset in 
bits/sample, [default=%default]")
+                     
+    (options, args) = parser.parse_args()
+    if len(args) != 0:
+        parser.print_help()
+        sys.exit(1)
+       
+    if options.modulation == 'bpsk':
+       options.order = 2
+    elif options.modulation == 'qpsk':
+        options.order = 4
+       
+    return (options, args)
+
+
+if __name__ == "__main__":
+    (options, args) = get_options()
+    print options
+    
+    # Applications have a 2-step initialization
+    
+    # Step 1: Create the application controller.  It will create
+    # the top block it manipulates.  The controller implements
+    # a property/value interface to allow setting, getting, and
+    # listening properties that affect the application operation.
+    controller = const_controller(order=options.order,
+                                  frame_size=1024,
+                                  frame_rate=30,
+                                  which=options.which,
+                                  decim=options.decim,
+                                  width_8=options.width_8,
+                                  no_hb=options.no_hb,
+                                  subdev_spec=options.rx_subdev_spec,
+                                  gain=options.gain,
+                                  freq=options.freq,
+                                  antenna=options.antenna,
+                                 bit_rate=options.rate,
+                                 costas_alpha=options.costas_alpha,
+                                 costas_max=options.costas_max,
+                                 mm_alpha=options.mm_alpha,
+                                 mm_max=options.mm_max)
+
+    # Step 2: Create the GUI and pass it the controller
+    # to manipulate.  The GUI code doesn't know anything about GNU
+    # Radio proper; it simply gets, sets, or listens to properties
+    # on the controller.  The 'GUI' can actually be a CLI batch
+    # program, an interactive shell, or anything that knows what to
+    # do with the controller properties.
+    #
+    #gui = const_gui(controller)
+    #gui.run()
+
+    # TEMPORARY
+    f = open('const.dat', 'wb')
+    def writer(frame):
+       f.write(frame)
+    controller.add_listener('const', writer)
+
+    controller.on_init()
+    try:
+       raw_input("Press return to stop.")
+    except KeyboardInterrupt:
+       pass
+       
+    controller.on_exit()


Property changes on: gnuradio/branches/features/experimental-gui/usrp_const.py
___________________________________________________________________
Name: svn:executable
   + *





reply via email to

[Prev in Thread] Current Thread [Next in Thread]