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

Revision 389, 9.0 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#!/usr/bin/env python
2#
3# Copyright 2005,2006,2007,2009 Free Software Foundation, Inc.
4#
5# This file is part of GNU Radio
6#
7# GNU Radio is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 3, or (at your option)
10# any later version.
11#
12# GNU Radio is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with GNU Radio; see the file COPYING.  If not, write to
19# the Free Software Foundation, Inc., 51 Franklin Street,
20# Boston, MA 02110-1301, USA.
21#
22
23from gnuradio import gr, gru, blks2
24from gnuradio import usrp
25from gnuradio import eng_notation
26import copy
27import sys
28
29# from current dir
30from pick_bitrate import pick_rx_bitrate
31import usrp_options
32
33# /////////////////////////////////////////////////////////////////////////////
34#                              receive path
35# /////////////////////////////////////////////////////////////////////////////
36
37class receive_path(gr.hier_block2):
38    def __init__(self, demod_class, rx_callback, options):
39
40        gr.hier_block2.__init__(self, "receive_path",
41                                gr.io_signature(0, 0, 0), # Input signature
42                                gr.io_signature(0, 0, 0)) # Output signature
43
44        options = copy.copy(options)    # make a copy so we can destructively modify
45
46        self._verbose            = options.verbose
47        self._rx_freq            = options.rx_freq         # receiver's center frequency
48        self._rx_gain            = options.rx_gain         # receiver's gain
49        self._bitrate            = options.bitrate         # desired bit rate
50        self._decim              = options.decim           # Decimating rate for the USRP (prelim)
51        self._samples_per_symbol = options.samples_per_symbol  # desired samples/symbol
52
53        self._rx_callback   = rx_callback      # this callback is fired when there's a packet available
54        self._demod_class   = demod_class      # the demodulator_class we're using
55
56        if self._rx_freq is None:
57            sys.stderr.write("-f FREQ or --freq FREQ or --rx-freq FREQ must be specified\n")
58            raise SystemExit
59
60        # Set up USRP source; also adjusts decim, samples_per_symbol, and bitrate
61        self._setup_usrp_source(options)
62
63        if options.show_rx_gain_range:
64            print "Rx Gain Range: minimum = %g, maximum = %g, step size = %g"%tuple(self.u.gain_range())
65
66        self.set_gain(options.rx_gain)
67
68        # Set RF frequency
69        ok = self.set_freq(self._rx_freq)
70        if not ok:
71            print "Failed to set Rx frequency to %s" % (eng_notation.num_to_str(self._rx_freq))
72            raise ValueError, eng_notation.num_to_str(self._rx_freq)
73
74        # copy the final answers back into options for use by demodulator
75        options.samples_per_symbol = self._samples_per_symbol
76        options.bitrate = self._bitrate
77        options.decim = self._decim
78
79        # Get demod_kwargs
80        demod_kwargs = self._demod_class.extract_kwargs_from_options(options)
81
82        # Design filter to get actual channel we want
83        sw_decim = 1
84        chan_coeffs = gr.firdes.low_pass (1.0,                  # gain
85                                          sw_decim * self._samples_per_symbol, # sampling rate
86                                          1.0,                  # midpoint of trans. band
87                                          0.5,                  # width of trans. band
88                                          gr.firdes.WIN_HANN)   # filter type
89
90        # Decimating channel filter
91        # complex in and out, float taps
92        self.chan_filt = gr.fft_filter_ccc(sw_decim, chan_coeffs)
93        #self.chan_filt = gr.fir_filter_ccf(sw_decim, chan_coeffs)
94
95        # receiver
96        self.packet_receiver = \
97            blks2.demod_pkts(self._demod_class(**demod_kwargs),
98                             access_code=None,
99                             callback=self._rx_callback,
100                             threshold=-1)
101   
102        # Carrier Sensing Blocks
103        alpha = 0.001
104        thresh = 30   # in dB, will have to adjust
105
106        if options.log_rx_power == True:
107            self.probe = gr.probe_avg_mag_sqrd_cf(thresh,alpha)
108            self.power_sink = gr.file_sink(gr.sizeof_float, "rxpower.dat")
109            self.connect(self.chan_filt, self.probe, self.power_sink)
110        else:
111            self.probe = gr.probe_avg_mag_sqrd_c(thresh,alpha)
112            self.connect(self.chan_filt, self.probe)
113
114        # Display some information about the setup
115        if self._verbose:
116            self._print_verbage()
117           
118        self.connect(self.u, self.chan_filt, self.packet_receiver)
119
120    def _setup_usrp_source(self, options):
121
122        self.u = usrp_options.create_usrp_source(options)
123        adc_rate = self.u.adc_rate()
124
125        # derive values of bitrate, samples_per_symbol, and decim from desired info
126        (self._bitrate, self._samples_per_symbol, self._decim) = \
127            pick_rx_bitrate(self._bitrate, self._demod_class.bits_per_symbol(), \
128                            self._samples_per_symbol, self._decim, adc_rate)
129
130        self.u.set_decim(self._decim)
131
132    def set_freq(self, target_freq):
133        """
134        Set the center frequency we're interested in.
135
136        @param target_freq: frequency in Hz
137        @rypte: bool
138
139        Tuning is a two step process.  First we ask the front-end to
140        tune as close to the desired frequency as it can.  Then we use
141        the result of that operation and our target_frequency to
142        determine the value for the digital up converter.
143        """
144        return self.u.set_center_freq(target_freq)
145
146    def set_gain(self, gain):
147        """
148        Sets the analog gain in the USRP
149        """
150        return self.u.set_gain(gain)
151       
152    def bitrate(self):
153        return self._bitrate
154
155    def samples_per_symbol(self):
156        return self._samples_per_symbol
157
158    def decim(self):
159        return self._decim
160
161    def carrier_sensed(self):
162        """
163        Return True if we think carrier is present.
164        """
165        #return self.probe.level() > X
166        return self.probe.unmuted()
167
168    def carrier_threshold(self):
169        """
170        Return current setting in dB.
171        """
172        return self.probe.threshold()
173
174    def set_carrier_threshold(self, threshold_in_db):
175        """
176        Set carrier threshold.
177
178        @param threshold_in_db: set detection threshold
179        @type threshold_in_db:  float (dB)
180        """
181        self.probe.set_threshold(threshold_in_db)
182   
183    @staticmethod
184    def add_options(normal, expert):
185        """
186        Adds receiver-specific options to the Options Parser
187        """
188        add_freq_option(normal)
189        if not normal.has_option("--bitrate"):
190            normal.add_option("-r", "--bitrate", type="eng_float", default=None,
191                              help="specify bitrate.  samples-per-symbol and interp/decim will be derived.")
192        usrp_options.add_rx_options(normal, expert)
193        normal.add_option("-v", "--verbose", action="store_true", default=False)
194        expert.add_option("-S", "--samples-per-symbol", type="int", default=None,
195                          help="set samples/symbol [default=%default]")
196        expert.add_option("", "--rx-freq", type="eng_float", default=None,
197                          help="set Rx frequency to FREQ [default=%default]", metavar="FREQ")
198        expert.add_option("", "--log", action="store_true", default=False,
199                          help="Log all parts of flow graph to files (CAUTION: lots of data)")
200        expert.add_option("", "--log-rx-power", action="store_true", default=False,
201                          help="Log receive signal power to file (CAUTION: lots of data)")
202
203    def _print_verbage(self):
204        """
205        Prints information about the receive path
206        """
207        print "\nReceive Path:"
208        print "USRP %s"    % (self.u,)
209        print "Rx gain:         %g"    % (self.u.gain(),)
210        print "modulation:      %s"    % (self._demod_class.__name__)
211        print "bitrate:         %sb/s" % (eng_notation.num_to_str(self._bitrate))
212        print "samples/symbol:  %3d"   % (self._samples_per_symbol)
213        print "decim:           %3d"   % (self._decim)
214        print "Rx Frequency:    %s"    % (eng_notation.num_to_str(self._rx_freq))
215
216def add_freq_option(parser):
217    """
218    Hackery that has the -f / --freq option set both tx_freq and rx_freq
219    """
220    def freq_callback(option, opt_str, value, parser):
221        parser.values.rx_freq = value
222        parser.values.tx_freq = value
223
224    if not parser.has_option('--freq'):
225        parser.add_option('-f', '--freq', type="eng_float",
226                          action="callback", callback=freq_callback,
227                          help="set Tx and/or Rx frequency to FREQ [default=%default]",
228                          metavar="FREQ")
Note: See TracBrowser for help on using the browser.