root/vtcross/trunk/src/cognitive_engines/DSA_CE/examples/gnuradio-examples/transmit_path.py @ 389

Revision 389, 8.9 KB (checked in by trnewman, 15 years ago)

Added DSA CBR reference implementation.
Added simple python example application for DSA CBR.
Added GNUradio python application that uses CROSS and the DSA CBR.

Fixed several bugs in the socket interface.

Line 
1#
2# Copyright 2005,2006,2007,2009 Free Software Foundation, Inc.
3#
4# This file is part of GNU Radio
5#
6# GNU Radio is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 3, or (at your option)
9# any later version.
10#
11# GNU Radio is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with GNU Radio; see the file COPYING.  If not, write to
18# the Free Software Foundation, Inc., 51 Franklin Street,
19# Boston, MA 02110-1301, USA.
20#
21
22from gnuradio import gr, gru, blks2
23from gnuradio import usrp
24from gnuradio import eng_notation
25
26import copy
27import sys
28
29# from current dir
30from pick_bitrate import pick_tx_bitrate
31import usrp_options
32
33# /////////////////////////////////////////////////////////////////////////////
34#                              transmit path
35# /////////////////////////////////////////////////////////////////////////////
36
37class transmit_path(gr.hier_block2):
38    def __init__(self, modulator_class, options):
39        '''
40        See below for what options should hold
41        '''
42        gr.hier_block2.__init__(self, "transmit_path",
43                                gr.io_signature(0, 0, 0), # Input signature
44                                gr.io_signature(0, 0, 0)) # Output signature
45
46        options = copy.copy(options)    # make a copy so we can destructively modify
47
48        self._verbose            = options.verbose
49        self._tx_freq            = options.tx_freq         # tranmitter's center frequency
50        self._tx_amplitude       = options.tx_amplitude    # digital amplitude sent to USRP
51        self._bitrate            = options.bitrate         # desired bit rate
52        self._interp             = options.interp          # interpolating rate for the USRP (prelim)
53        self._samples_per_symbol = options.samples_per_symbol  # desired samples/baud
54        self._use_whitener_offset = options.use_whitener_offset # increment start of whitener XOR data
55       
56        self._modulator_class = modulator_class         # the modulator_class we are using
57   
58        if self._tx_freq is None:
59            sys.stderr.write("-f FREQ or --freq FREQ or --tx-freq FREQ must be specified\n")
60            raise SystemExit
61
62        # Set up USRP sink; also adjusts interp, samples_per_symbol, and bitrate
63        self._setup_usrp_sink(options)
64
65        if options.show_tx_ampl_range:
66            print "Tx Amplitude Range: minimum = %g, maximum = %g"%tuple(self.u.ampl_range())
67
68        # copy the final answers back into options for use by modulator
69        options.samples_per_symbol = self._samples_per_symbol
70        options.bitrate = self._bitrate
71        options.interp = self._interp
72
73        # Get mod_kwargs
74        mod_kwargs = self._modulator_class.extract_kwargs_from_options(options)
75
76        # Set center frequency of USRP
77        ok = self.set_freq(self._tx_freq)
78        if not ok:
79            print "Failed to set Tx frequency to %s" % (eng_notation.num_to_str(self._tx_freq),)
80            raise ValueError
81   
82        # transmitter
83        self.packet_transmitter = \
84            blks2.mod_pkts(self._modulator_class(**mod_kwargs),
85                           access_code=None,
86                           msgq_limit=4,
87                           pad_for_usrp=True,
88                           use_whitener_offset=options.use_whitener_offset)
89
90
91        # Set the USRP for maximum transmit gain
92        # (Note that on the RFX cards this is a nop.)
93        self.set_gain(self.u.gain_range()[1])
94
95        self.amp = gr.multiply_const_cc(1)
96        self.set_tx_amplitude(self._tx_amplitude)
97
98        # Display some information about the setup
99        if self._verbose:
100            self._print_verbage()
101
102        # Create and setup transmit path flow graph
103        self.connect(self.packet_transmitter, self.amp, self.u)
104
105    def _setup_usrp_sink(self, options):
106        """
107        Creates a USRP sink, determines the settings for best bitrate,
108        and attaches to the transmitter's subdevice.
109        """
110        self.u = usrp_options.create_usrp_sink(options)
111        dac_rate = self.u.dac_rate();
112
113        # derive values of bitrate, samples_per_symbol, and interp from desired info
114        (self._bitrate, self._samples_per_symbol, self._interp) = \
115            pick_tx_bitrate(self._bitrate, self._modulator_class.bits_per_symbol(),
116                            self._samples_per_symbol, self._interp, dac_rate)
117       
118        self.u.set_interp(self._interp)
119        print "printing interpolation ",self._interp,"\n"
120
121    def set_freq(self, target_freq):
122        """
123        Set the center frequency we're interested in.
124
125        @param target_freq: frequency in Hz
126        @rypte: bool
127
128        Tuning is a two step process.  First we ask the front-end to
129        tune as close to the desired frequency as it can.  Then we use
130        the result of that operation and our target_frequency to
131        determine the value for the digital up converter.
132        """
133        return self.u.set_center_freq(target_freq)
134       
135    def set_gain(self, gain):
136        """
137        Sets the analog gain in the USRP
138        """
139        return self.u.set_gain(gain)
140
141    def set_tx_amplitude(self, ampl):
142        """
143        Sets the transmit amplitude sent to the USRP
144        @param ampl the amplitude or None for automatic
145        """
146        ampl_range = self.u.ampl_range()
147        if ampl is None: ampl = (ampl_range[1] - ampl_range[0])*0.15 + ampl_range[0]
148        self._tx_amplitude = max(ampl_range[0], min(ampl, ampl_range[1]))
149        self.amp.set_k(self._tx_amplitude)
150
151    def send_pkt(self, payload='', eof=False):
152        """
153        Calls the transmitter method to send a packet
154        """
155        return self.packet_transmitter.send_pkt(payload, eof)
156       
157    def bitrate(self):
158        return self._bitrate
159
160    def samples_per_symbol(self):
161        return self._samples_per_symbol
162
163    def interp(self):
164        return self._interp
165
166    def add_options(normal, expert):
167        """
168        Adds transmitter-specific options to the Options Parser
169        """
170        add_freq_option(normal)
171        if not normal.has_option('--bitrate'):
172            normal.add_option("-r", "--bitrate", type="eng_float", default=None,
173                              help="specify bitrate.  samples-per-symbol and interp/decim will be derived.")
174        usrp_options.add_tx_options(normal, expert)
175        normal.add_option("--tx-amplitude", type="eng_float", default=None, metavar="AMPL",
176                          help="set transmitter digital amplitude [default=midpoint].  See also --show-tx-ampl-range")
177        normal.add_option("--show-tx-ampl-range", action="store_true", default=False,
178                          help="print min and max Tx amplitude available")
179        normal.add_option("-v", "--verbose", action="store_true", default=False)
180        expert.add_option("-S", "--samples-per-symbol", type="int", default=None,
181                          help="set samples/symbol [default=%default]")
182        expert.add_option("", "--tx-freq", type="eng_float", default=None,
183                          help="set transmit frequency to FREQ [default=%default]", metavar="FREQ")
184        expert.add_option("", "--log", action="store_true", default=False,
185                          help="Log all parts of flow graph to file (CAUTION: lots of data)")
186        expert.add_option("","--use-whitener-offset", action="store_true", default=False,
187                          help="make sequential packets use different whitening")
188
189    # Make a static method to call before instantiation
190    add_options = staticmethod(add_options)
191
192    def _print_verbage(self):
193        """
194        Prints information about the transmit path
195        """
196        print "Using TX d'board %s"    % (self.u,)
197        print "Tx amplitude     %s"    % (self._tx_amplitude)
198        print "modulation:      %s"    % (self._modulator_class.__name__)
199        print "bitrate:         %sb/s" % (eng_notation.num_to_str(self._bitrate))
200        print "samples/symbol:  %3d"   % (self._samples_per_symbol)
201        print "interp:          %3d"   % (self._interp)
202        print "Tx Frequency:    %s"    % (eng_notation.num_to_str(self._tx_freq))
203       
204
205def add_freq_option(parser):
206    """
207    Hackery that has the -f / --freq option set both tx_freq and rx_freq
208    """
209    def freq_callback(option, opt_str, value, parser):
210        parser.values.rx_freq = value
211        parser.values.tx_freq = value
212
213    if not parser.has_option('--freq'):
214        parser.add_option('-f', '--freq', type="eng_float",
215                          action="callback", callback=freq_callback,
216                          help="set Tx and/or Rx frequency to FREQ [default=%default]",
217                          metavar="FREQ")
Note: See TracBrowser for help on using the browser.