Changeset 330

Show
Ignore:
Timestamp:
07/17/09 13:18:46 (15 years ago)
Author:
sriram
Message:

Hardcoding some more receive path options

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • vtcross/branches/sriram/benchmark_txrxnode1.py

    r327 r330  
    77from gnuradio import optfir, window 
    88from gnuradio import usrp 
    9 from gnuradio.eng_option import eng_option 
    10 from usrpm import usrp_dbid 
     9#from gnuradio.eng_option import eng_option 
     10#from usrpm import usrp_dbid 
    1111########## 
    1212from gnuradio.eng_option import eng_option 
     
    1818from transmit_path import transmit_path 
    1919from receive_path import receive_path 
     20import spec_sense_path 
    2021 
    2122global sync_status 
     
    3536        self.rxpath = receive_path(demod_class, rx_callback, options_rx) 
    3637        self.txpath = transmit_path(mod_class, options_tx) 
    37         self.connect(self.txpath); 
    38         self.connect(self.rxpath); 
    39  
    40  
    41 ##################### Spectrum sense specific classes########################################################### 
    42 class tune(gr.feval_dd): 
    43     """ 
    44     This class allows C++ code to callback into python. 
    45     """ 
    46     def __init__(self, tb): 
    47         gr.feval_dd.__init__(self) 
    48         self.tb = tb 
    49  
    50     def eval(self, ignore): 
    51         """ 
    52         This method is called from gr.bin_statistics_f when it wants to change 
    53         the center frequency.  This method tunes the front end to the new center 
    54         frequency, and returns the new frequency as its result. 
    55         """ 
    56         try: 
    57             # We use this try block so that if something goes wrong from here  
    58             # down, at least we'll have a prayer of knowing what went wrong. 
    59             # Without this, you get a very mysterious: 
    60             # 
    61             #   terminate called after throwing an instance of 'Swig::DirectorMethodException' 
    62             #   Aborted 
    63             # 
    64             # message on stderr.  Not exactly helpful ;) 
    65  
    66             new_freq = self.tb.set_next_freq() 
    67             return new_freq 
    68  
    69         except Exception, e: 
    70             print "tune: Exception: ", e 
    71  
    72  
    73 class parse_msg(object): 
    74     def __init__(self, msg): 
    75         self.center_freq = msg.arg1() 
    76         self.vlen = int(msg.arg2()) 
    77         assert(msg.length() == self.vlen * gr.sizeof_float) 
    78  
    79         # FIXME consider using Numarray or NumPy vector 
    80         t = msg.to_string() 
    81         self.raw_data = t 
    82         self.data = struct.unpack('%df' % (self.vlen,), t) 
    83  
    84  
    85 class spec_sense_top_block(gr.top_block): 
    86  
    87     def __init__(self,min_f,max_f): 
    88         gr.top_block.__init__(self) 
    89  
    90         usage = "usage: %prog [options] min_freq max_freq" 
    91         parser = OptionParser(option_class=eng_option, usage=usage) 
    92         parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=(0,0), 
    93                           help="select USRP Rx side A or B (default=A)") 
    94         parser.add_option("-g", "--gain", type="eng_float", default=None, 
    95                           help="set gain in dB (default is midpoint)") 
    96         parser.add_option("", "--tune-delay", type="eng_float", default=1e-3, metavar="SECS", 
    97                           help="time to delay (in seconds) after changing frequency [default=%default]") 
    98         parser.add_option("", "--dwell-delay", type="eng_float", default=10e-3, metavar="SECS", 
    99                           help="time to dwell (in seconds) at a given frequncy [default=%default]") 
    100         parser.add_option("-F", "--fft-size", type="int", default=256, 
    101                           help="specify number of FFT bins [default=%default]") 
    102         parser.add_option("-d", "--decim", type="intx", default=16, 
    103                           help="set decimation to DECIM [default=%default]") 
    104         parser.add_option("", "--real-time", action="store_true", default=False, 
    105                           help="Attempt to enable real-time scheduling") 
    106         parser.add_option("-B", "--fusb-block-size", type="int", default=0, 
    107                           help="specify fast usb block size [default=%default]") 
    108         parser.add_option("-N", "--fusb-nblocks", type="int", default=0, 
    109                           help="specify number of fast usb blocks [default=%default]") 
    110  
    111         (options, args) = parser.parse_args() 
    112         #if len(args) != 2: 
    113          #   parser.print_help() 
    114          #   sys.exit(1) 
    115  
    116         #self.min_freq = eng_notation.str_to_num(args[0]) 
    117         self.min_freq = float(min_f) # setting min and max frequency inside the init rather than taking it from the command line 
    118         #self.max_freq = eng_notation.str_to_num(args[1]) 
    119         self.max_freq = float(max_f) 
    120  
    121         if self.min_freq > self.max_freq: 
    122             self.min_freq, self.max_freq = self.max_freq, self.min_freq   # swap them 
    123  
    124         self.fft_size = options.fft_size 
    125  
    126  
    127         if not options.real_time: 
    128             realtime = False 
    129         else: 
    130             # Attempt to enable realtime scheduling 
    131             r = gr.enable_realtime_scheduling() 
    132             if r == gr.RT_OK: 
    133                 realtime = True 
    134             else: 
    135                 realtime = False 
    136                 print "Note: failed to enable realtime scheduling" 
    137  
    138         # If the user hasn't set the fusb_* parameters on the command line, 
    139         # pick some values that will reduce latency. 
    140  
    141         if 1: 
    142             if options.fusb_block_size == 0 and options.fusb_nblocks == 0: 
    143                 if realtime:                        # be more aggressive 
    144                     options.fusb_block_size = gr.prefs().get_long('fusb', 'rt_block_size', 1024) 
    145                     options.fusb_nblocks    = gr.prefs().get_long('fusb', 'rt_nblocks', 16) 
    146                 else: 
    147                     options.fusb_block_size = gr.prefs().get_long('fusb', 'block_size', 4096) 
    148                     options.fusb_nblocks    = gr.prefs().get_long('fusb', 'nblocks', 16) 
    149      
    150         #print "fusb_block_size =", options.fusb_block_size 
    151         #print "fusb_nblocks    =", options.fusb_nblocks 
    152  
    153         # build graph 
    154          
    155         self.u = usrp.source_c(fusb_block_size=options.fusb_block_size, 
    156                                fusb_nblocks=options.fusb_nblocks) 
    157  
    158  
    159         adc_rate = self.u.adc_rate()                # 64 MS/s 
    160         usrp_decim = options.decim 
    161         self.u.set_decim_rate(usrp_decim) 
    162         usrp_rate = adc_rate / usrp_decim 
    163  
    164         self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) 
    165         self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) 
    166         print "Using RX d'board %s" % (self.subdev.side_and_name(),) 
    167  
    168  
    169         s2v = gr.stream_to_vector(gr.sizeof_gr_complex, self.fft_size) 
    170  
    171         mywindow = window.blackmanharris(self.fft_size) 
    172         fft = gr.fft_vcc(self.fft_size, True, mywindow) 
    173         power = 0 
    174         for tap in mywindow: 
    175             power += tap*tap 
    176              
    177         c2mag = gr.complex_to_mag_squared(self.fft_size) 
    178         print "print c2mag ",c2mag,"\n" 
    179         # FIXME the log10 primitive is dog slow 
    180         log = gr.nlog10_ff(10, self.fft_size, 
    181                            -20*math.log10(self.fft_size)-10*math.log10(power/self.fft_size)) 
    182                  
    183         # Set the freq_step to 75% of the actual data throughput. 
    184         # This allows us to discard the bins on both ends of the spectrum. 
    185  
    186         self.freq_step = 0.75 * usrp_rate 
    187         self.min_center_freq = self.min_freq + self.freq_step/2 
    188         nsteps = math.ceil((self.max_freq - self.min_freq) / self.freq_step) 
    189         self.max_center_freq = self.min_center_freq + (nsteps * self.freq_step) 
    190  
    191         self.next_freq = self.min_center_freq 
    192          
    193         tune_delay  = max(0, int(round(options.tune_delay * usrp_rate / self.fft_size)))  # in fft_frames 
    194         dwell_delay = max(1, int(round(options.dwell_delay * usrp_rate / self.fft_size))) # in fft_frames 
    195  
    196         self.msgq = gr.msg_queue(16) 
    197         self._tune_callback = tune(self)        # hang on to this to keep it from being GC'd 
    198         stats = gr.bin_statistics_f(self.fft_size, self.msgq, 
    199                                     self._tune_callback, tune_delay, dwell_delay) 
    200  
    201         # FIXME leave out the log10 until we speed it up 
    202         #self.connect(self.u, s2v, fft, c2mag, log, stats) 
    203         self.connect(self.u, s2v, fft, c2mag, stats) 
    204  
    205         if options.gain is None: 
    206             # if no gain was specified, use the mid-point in dB 
    207             g = self.subdev.gain_range() 
    208             options.gain = float(g[0]+g[1])/2 
    209  
    210         self.set_gain(options.gain) 
    211         print "gain =", options.gain 
    212  
    213  
    214     def set_next_freq(self): 
    215         target_freq = self.next_freq 
    216         self.next_freq = self.next_freq + self.freq_step 
    217         if self.next_freq >= self.max_center_freq: 
    218             self.next_freq = self.min_center_freq 
    219  
    220         if not self.set_freq(target_freq): 
    221             print "Failed to set frequency to", target_freq 
    222  
    223         return target_freq 
    224                            
    225  
    226     def set_freq(self, target_freq): 
    227         """ 
    228         Set the center frequency we're interested in. 
    229  
    230         @param target_freq: frequency in Hz 
    231         @rypte: bool 
    232  
    233         Tuning is a two step process.  First we ask the front-end to 
    234         tune as close to the desired frequency as it can.  Then we use 
    235         the result of that operation and our target_frequency to 
    236         determine the value for the digital down converter. 
    237         """ 
    238         return self.u.tune(0, self.subdev, target_freq) 
    239  
    240  
    241     def set_gain(self, gain): 
    242         self.subdev.set_gain(gain) 
    243  
    244     def set_min_max_freq(self,minimum,maximum):# setting min and max frequency  
    245         self.min_freq = float(minimum)  
    246         self.max_freq = float(maximum) 
    247  
    248     def get_avg_power(self,trials): 
    249         power_sum = 0 #sum of powers(each power value is determined by adding the 'fft square' points..these fft square points are essentially points from  the PSD curve...and adding them gives us the power contained in the spectrum) 
    250         counter = 0 
    251         _trials = int(trials) 
    252         while counter < _trials : 
    253  
    254                 # Get the next message sent from the C++ code (blocking call). 
    255                 # It contains the center frequency and the mag squared of the fft 
    256                 m = parse_msg(self.msgq.delete_head()) 
    257                 print "printing mag sq of fft ",sum(m.data),"\n" 
    258                 #if sum(m.data) > 1e12: 
    259                 power_sum = power_sum + sum(m.data) 
    260                 # Print center freq so we know that something is happening... 
    261                 #print m.center_freq 
    262                 counter +=1 
    263                 # FIXME do something useful with the data... 
    264          
    265                 # m.data are the mag_squared of the fft output (they are in the 
    266                 # standard order.  I.e., bin 0 == DC.) 
    267                 # You'll probably want to do the equivalent of "fftshift" on them 
    268                 # m.raw_data is a string that contains the binary floats. 
    269                 # You could write this as binary to a file. 
    270  
    271         avg_power = power_sum/_trials 
    272         print "printing average power ",avg_power,"\n" 
    273         return avg_power 
    274  
    275 ######################## end of spectrum sense specific classes ############################################################# 
     38         
     39        ########connect for the spectrum sense######### 
     40        default_min_freq = 462.4825e6 #80 Khz to the left of channel 1 (462.5625e6) in frs band  
     41        default_max_freq = 462.6425e6 #80 Khz to the right of channel 1 (462.5625e6) in frs band  
     42        self.sp_sense_path = spec_sense_path.spec_sense_top_block(default_min_freq,default_min_freq) 
     43        self.connect(self.sp_sense_path.u, self.sp_sense_path.s2v, self.sp_sense_path.fft, self.sp_sense_path.c2mag, self.sp_sense_path.stats) 
     44        #self.connect(self.txpath); 
     45        #self.connect(self.rxpath); 
    27646 
    27747         
     
    362132        sys.exit(1) 
    363133    ############# Setting some default values for tx side of the block 
    364     options_tx.tx_freq = 462.5625e6 #setting default tx_freq value 
     134    options_tx.tx_freq = 462.5625e6  
    365135    options_tx.samples_per_symbol =  2 
    366136    options_tx.modulation = 'dbpsk' 
     137    options_tx.fusb_block_size = 4096 
     138    options_tx.fusb_nblocks = 16 
    367139    ############# 
    368140    if options_tx.tx_freq is None: 
     
    409181    options_rx.samples_per_symbol =  2 
    410182    options_rx.modulation = 'dbpsk' 
     183    options_rx.fusb_block_size = 4096 
     184    options_rx.fusb_nblocks = 16 
    411185    ############# 
    412186    if options_rx.rx_freq is None: 
     
    420194    ######################## adding another top block for usrp spectrum sense ######################## 
    421195    trials = 10 
    422     default_min_freq = 462.4825e6 #80 Khz to the left of channel 1 (462.5625e6) in frs band  
    423     default_max_freq = 462.6425e6 #80 Khz to the right of channel 1 (462.5625e6) in frs band  
    424     tb_spec_sense = spec_sense_top_block(default_min_freq,default_min_freq) 
    425     tb_spec_sense.subdev.select_rx_antenna('RX2') 
    426     tb_spec_sense.start()              # start executing flow graph in another thread... 
    427     avg = tb_spec_sense.get_avg_power(trials) 
    428     print "printing the average power ",avg, "\n" 
    429     tb_spec_sense.stop()    
     196     
     197    #tb_spec_sense = spec_sense_top_block(default_min_freq,default_min_freq) 
     198    #tb_spec_sense.subdev.select_rx_antenna('RX2') 
     199    #tb_spec_sense.start()              # start executing flow graph in another thread... 
     200    #avg = tb_spec_sense.get_avg_power(trials) 
     201    #print "printing the average power ",avg, "\n" 
     202    #tb_spec_sense.stop()    
    430203     
    431204