예제 #1
0
	def setup_radiometer_common(self,n):
		# The IIR integration filter for post-detection
		self.integrator = gr.single_pole_iir_filter_ff(1.0)
		self.integrator.set_taps (1.0/self.bw)
		
		if (self.use_notches == True):
			self.compute_notch_taps(self.notches)
			if (n == 2):
				self.notch_filt1 = gr.fft_filter_ccc(1, self.notch_taps)
				self.notch_filt2 = gr.fft_filter_ccc(1, self.notch_taps)
			else:
				self.notch_filt = gr.fft_filter_ccc(1, self.notch_taps)


		# Signal probe
		self.probe = gr.probe_signal_f()

		#
		# Continuum calibration stuff
		#
		x = self.calib_coeff/100.0
		self.cal_mult = gr.multiply_const_ff(self.calib_coeff/100.0)
		self.cal_offs = gr.add_const_ff(self.calib_offset*(x*8000))
		
		#
		# Mega decimator after IIR filter
		#
		if (self.switch_mode == False):
			self.keepn = gr.keep_one_in_n(gr.sizeof_float, self.bw)
		else:
			self.keepn = gr.keep_one_in_n(gr.sizeof_float, int(self.bw/2))
		
		#
		# For the Dicke-switching scheme
		#
		#self.switch = gr.multiply_const_ff(1.0)
		
		#
		if (self.switch_mode == True):
			self.vector = gr.vector_sink_f()
			self.swkeep = gr.keep_one_in_n(gr.sizeof_float, int(self.bw/3))
			self.mute = gr.keep_one_in_n(gr.sizeof_float, 1)
			self.cmute = gr.keep_one_in_n(gr.sizeof_float, int(1.0e9))
			self.cintegrator = gr.single_pole_iir_filter_ff(1.0/(self.bw/2))	
			self.cprobe = gr.probe_signal_f()
		else:
			self.mute = gr.multiply_const_ff(1.0)
			
			
		self.avg_reference_value = 0.0
		self.reference_level = gr.add_const_ff(0.0)
예제 #2
0
  def __init__ ( self, noise_power, coherence_time, taps ):
    gr.hier_block2.__init__(self,
      "fading_channel", 
      gr.io_signature( 1, 1, gr.sizeof_gr_complex ),
      gr.io_signature( 1, 1, gr.sizeof_gr_complex ) )

    inp = gr.kludge_copy( gr.sizeof_gr_complex )
    self.connect( self, inp )
    
    tap1_delay = gr.delay( gr.sizeof_gr_complex, 1 )
    tap2_delay = gr.delay( gr.sizeof_gr_complex, 2 )
    self.connect( inp, tap1_delay )
    self.connect( inp, tap2_delay )
    
    fd = 100
    z = numpy.arange(-fd+0.1,fd,0.1)
    t = numpy.sqrt(1. / ( pi * fd * numpy.sqrt( 1. - (z/fd)**2 ) ) )
    
    tap1_noise = ofdm.complex_white_noise( 0.0, taps[0] )
    tap1_filter = gr.fft_filter_ccc(1, t)
    self.connect( tap1_noise, tap1_filter )
    
    tap1_mult = gr.multiply_cc()
    self.connect( tap1_filter, (tap1_mult,0) )
    self.connect( tap1_delay, (tap1_mult,1) )
    
    tap2_noise = ofdm.complex_white_noise( 0.0, taps[1] )
    tap2_filter = gr.fft_filter_ccc(1, t)
    
    self.connect( tap2_noise, tap2_filter )
    
    tap2_mult = gr.multiply_cc()
    self.connect( tap2_filter, (tap2_mult,0) )
    self.connect( tap2_delay, (tap2_mult,1) )
    
    noise_src = ofdm.complex_white_noise( 0.0, sqrt( noise_power ) )
    chan = gr.add_cc()
    
    self.connect( inp, (chan,0) )
    self.connect( tap1_mult, (chan,1) )
    self.connect( tap2_mult, (chan,2) )
    self.connect( noise_src, (chan,3) )
    
    self.connect( chan, self )
    
    log_to_file( self, tap1_filter, "data/tap1_filter.compl")
    log_to_file( self, tap1_filter, "data/tap1_filter.float", mag=True)
    log_to_file( self, tap2_filter, "data/tap2_filter.compl")
    log_to_file( self, tap2_filter, "data/tap2_filter.float", mag=True)
예제 #3
0
    def __init__(self, noise_power, coherence_time, taps):
        gr.hier_block2.__init__(self, "fading_channel",
                                gr.io_signature(1, 1, gr.sizeof_gr_complex),
                                gr.io_signature(1, 1, gr.sizeof_gr_complex))

        inp = gr.kludge_copy(gr.sizeof_gr_complex)
        self.connect(self, inp)

        tap1_delay = gr.delay(gr.sizeof_gr_complex, 1)
        tap2_delay = gr.delay(gr.sizeof_gr_complex, 2)
        self.connect(inp, tap1_delay)
        self.connect(inp, tap2_delay)

        fd = 100
        z = numpy.arange(-fd + 0.1, fd, 0.1)
        t = numpy.sqrt(1. / (pi * fd * numpy.sqrt(1. - (z / fd)**2)))

        tap1_noise = ofdm.complex_white_noise(0.0, taps[0])
        tap1_filter = gr.fft_filter_ccc(1, t)
        self.connect(tap1_noise, tap1_filter)

        tap1_mult = gr.multiply_cc()
        self.connect(tap1_filter, (tap1_mult, 0))
        self.connect(tap1_delay, (tap1_mult, 1))

        tap2_noise = ofdm.complex_white_noise(0.0, taps[1])
        tap2_filter = gr.fft_filter_ccc(1, t)

        self.connect(tap2_noise, tap2_filter)

        tap2_mult = gr.multiply_cc()
        self.connect(tap2_filter, (tap2_mult, 0))
        self.connect(tap2_delay, (tap2_mult, 1))

        noise_src = ofdm.complex_white_noise(0.0, sqrt(noise_power))
        chan = gr.add_cc()

        self.connect(inp, (chan, 0))
        self.connect(tap1_mult, (chan, 1))
        self.connect(tap2_mult, (chan, 2))
        self.connect(noise_src, (chan, 3))

        self.connect(chan, self)

        log_to_file(self, tap1_filter, "data/tap1_filter.compl")
        log_to_file(self, tap1_filter, "data/tap1_filter.float", mag=True)
        log_to_file(self, tap2_filter, "data/tap2_filter.compl")
        log_to_file(self, tap2_filter, "data/tap2_filter.float", mag=True)
예제 #4
0
    def __init__(self, demod_class, rx_callback, options):
	gr.hier_block2.__init__(self, "receive_path",
				gr.io_signature(1, 1, gr.sizeof_gr_complex),
				gr.io_signature(0, 0, 0))
        
        options = copy.copy(options)    # make a copy so we can destructively modify

        self._verbose     = options.verbose
        self._bitrate     = options.bitrate  # desired bit rate

        self._rx_callback = rx_callback  # this callback is fired when a packet arrives
        self._demod_class = demod_class  # the demodulator_class we're using

        self._chbw_factor = options.chbw_factor # channel filter bandwidth factor

        # Get demod_kwargs
        demod_kwargs = self._demod_class.extract_kwargs_from_options(options)

        # Build the demodulator
        self.demodulator = self._demod_class(**demod_kwargs)

        # Make sure the channel BW factor is between 1 and sps/2
        # or the filter won't work.
        if(self._chbw_factor < 1.0 or self._chbw_factor > self.samples_per_symbol()/2):
            sys.stderr.write("Channel bandwidth factor ({0}) must be within the range [1.0, {1}].\n".format(self._chbw_factor, self.samples_per_symbol()/2))
            sys.exit(1)
        
        # Design filter to get actual channel we want
        sw_decim = 1
        chan_coeffs = gr.firdes.low_pass (1.0,                  # gain
                                          sw_decim * self.samples_per_symbol(), # sampling rate
                                          self._chbw_factor,    # midpoint of trans. band
                                          0.5,                  # width of trans. band
                                          gr.firdes.WIN_HANN)   # filter type
        self.channel_filter = gr.fft_filter_ccc(sw_decim, chan_coeffs)
        
        # receiver
        self.packet_receiver = \
            digital.demod_pkts(self.demodulator,
                               access_code=None,
                               callback=self._rx_callback,
                               threshold=-1)

        # Carrier Sensing Blocks
        alpha = 0.001
        thresh = 30   # in dB, will have to adjust
        self.probe = gr.probe_avg_mag_sqrd_c(thresh,alpha)

        # Display some information about the setup
        if self._verbose:
            self._print_verbage()

	# connect block input to channel filter
	self.connect(self, self.channel_filter)

        # connect the channel input filter to the carrier power detector
        self.connect(self.channel_filter, self.probe)

        # connect channel filter to the packet receiver
        self.connect(self.channel_filter, self.packet_receiver)
예제 #5
0
	def __init__(self, options, rx_callback):
		phy_base.__init__(self, options, rx_callback)

		# Receive chain
		demod_class = phy_psk.DEMODS[options.psk_modulation]
		demod_kwargs = demod_class.extract_kwargs_from_options(options)
		self._rx_demod = blks2.demod_pkts(
				demod_class(**demod_kwargs),
				callback=self._rx_callback)
		sw_decim = 1
		self._rx_chan_filt = gr.fft_filter_ccc(
				sw_decim, 
				gr.firdes.low_pass (
					1.0,								# gain
					sw_decim * self._rx_demod._demodulator.samples_per_symbol(),	# sampling rate
					1.0,								# midpoint of trans. band
					0.5,								# width of trans. band
					gr.firdes.WIN_HANN))						# filter type
		self.connect(self, self._rx_chan_filt, self._rx_demod)

		# Trasmit chain
		mod_class = phy_psk.MODS[options.psk_modulation]
		mod_kwargs = mod_class.extract_kwargs_from_options(options)
		self._tx_mod = blks2.mod_pkts(
				mod_class(**mod_kwargs),
				pad_for_usrp=True)
		self.connect(self._tx_mod, gr.kludge_copy(gr.sizeof_gr_complex), self)
 def reset_filter(self):
     bw = (float(self._occupied_tones) / float(self._fft_length)) / 2.0
     tb = bw*0.06
     chan_coeffs = gr.firdes.low_pass (1.0,                     # gain
                                       1.0,                     # sampling rate
                                       bw+tb,                   # midpoint of trans. band
                                       tb,                      # width of trans. band
                                       gr.firdes.WIN_HAMMING)   # filter type
     self.chan_filt = gr.fft_filter_ccc(1, chan_coeffs)
예제 #7
0
    def test_ccc_get0(self):
        random.seed(0)
        for i in xrange(25):
            ntaps = int(random.uniform(2, 100))
            taps = make_random_complex_tuple(ntaps)

            op = gr.fft_filter_ccc(1, taps)
            result_data = op.taps()
            #print result_data

            self.assertComplexTuplesAlmostEqual(taps, result_data, 4)
예제 #8
0
    def __init__(self, demod_class, rx_callback, options):
        gr.hier_block2.__init__(
            self,
            "receive_path",
            gr.io_signature(1, 1, gr.sizeof_gr_complex),  # Input signature
            gr.io_signature(0, 0, 0))  # Output signature

        options = copy.copy(
            options)  # make a copy so we can destructively modify

        self._verbose = options.verbose
        self._bitrate = options.bitrate  # desired bit rate
        self._samples_per_symbol = options.samples_per_symbol  # desired samples/symbol

        self._rx_callback = rx_callback  # this callback is fired when there's a packet available
        self._demod_class = demod_class  # the demodulator_class we're using

        # Get demod_kwargs
        demod_kwargs = self._demod_class.extract_kwargs_from_options(options)

        # Design filter to get actual channel we want
        sw_decim = 1
        chan_coeffs = gr.firdes.low_pass(
            1.0,  # gain
            sw_decim * self._samples_per_symbol,  # sampling rate
            1.0,  # midpoint of trans. band
            0.5,  # width of trans. band
            gr.firdes.WIN_HANN)  # filter type
        self.channel_filter = gr.fft_filter_ccc(sw_decim, chan_coeffs)

        # receiver
        self.packet_receiver = \
            blks2.demod_pkts(self._demod_class(**demod_kwargs),
                             access_code=None,
                             callback=self._rx_callback,
                             threshold=-1)

        # Carrier Sensing Blocks
        alpha = 0.001
        thresh = 30  # in dB, will have to adjust
        self.probe = gr.probe_avg_mag_sqrd_c(thresh, alpha)

        # Display some information about the setup
        if self._verbose:
            self._print_verbage()

        # connect block input to channel filter
        self.connect(self, self.channel_filter)

        # connect the channel input filter to the carrier power detector
        self.connect(self.channel_filter, self.probe)

        # connect channel filter to the packet receiver
        self.connect(self.channel_filter, self.packet_receiver)
예제 #9
0
    def __init__(self, principal_gui, rx_callback, options):
        gr.hier_block2.__init__(self, "receive_path",
                                gr.io_signature(0,0,0), # the 1,1 indicate the minimum, maximum  stream in input
                                gr.io_signature(0,0,0))                    # the 0,0 indicate the minimum, maximum  stream in output
        
        #local setup usrp source creat self.usrp source 
        self._setup_usrp_source(options)
        
        options = copy.copy(options) # Make copy of the received options
        
        self._verbose           = options.verbose
        self._bitrate           = options.rate            # The bit rate transmission
        self._samples_per_symbol= options.samples_per_symbol # samples/sample
        
        self._rx_callback   = rx_callback        #This callback is fired (declanche) when there's packet is available
        self.demodulator    = bpsk_demodulator(principal_gui, options)      #The demodulator used 
        
        #Designe filter to get actual channel we want
        sw_decim = 1
        
        #Create the low pass filter 
        chan_coeffs = gr.firdes.low_pass (1.0,                                  #gain
                                          sw_decim * self._samples_per_symbol,  #sampling rate
                                          1.0,                                  #midpoint of trans band
                                          0.5,                                  #width of trans band
                                          gr.firdes.WIN_HAMMING)                #filter type
        self.channel_filter = gr.fft_filter_ccc(sw_decim, chan_coeffs)
        

        self.packet_receiver = ieee_pkt_receiver.ieee_pkt_receiver_868_915(self, 
                                                                   gui = principal_gui,
                                                                   demodulator = self.demodulator,
                                                                   callback = rx_callback,
                                                                   sps = self._samples_per_symbol,
                                                                   symbol_rate = self._bitrate,
                                                                   threshold = -1) 
            
        #Carrier Sensing Block (ecoute du canal)
        alpha = 0.001
        # Carrier Sensing with dB, will have to adjust
        thresh = 30 
        #construct analyser of carrier (c'est un sink) 
        self.probe = gr.probe_avg_mag_sqrd_c(thresh, alpha)
        
        #display information about the setup
        if self._verbose:
            self._print_verbage()
        
        #self.squelch = gr.pwr_squelch_cc(50, 1, 0, True)
        #connect the input block to channel filter
        #connect the blocks with usrp, the  self.usrp is created in _setup_usrp_source
        self.squelch = gr.pwr_squelch_cc(50, 1, 0, True)
        self.connect(self._usrp,  self.packet_receiver)
예제 #10
0
    def __init__(self, demod_class, rx_callback, options):
        gr.hier_block2.__init__(
            self,
            "receive_path",
            gr.io_signature(1, 1, gr.sizeof_gr_complex),  # Input signature
            gr.io_signature(0, 0, 0),
        )  # Output signature

        options = copy.copy(options)  # make a copy so we can destructively modify

        self._verbose = options.verbose
        self._bitrate = options.bitrate  # desired bit rate
        self._samples_per_symbol = options.samples_per_symbol  # desired samples/symbol

        self._rx_callback = rx_callback  # this callback is fired when there's a packet available
        self._demod_class = demod_class  # the demodulator_class we're using

        # Get demod_kwargs
        demod_kwargs = self._demod_class.extract_kwargs_from_options(options)

        # Design filter to get actual channel we want
        sw_decim = 1
        chan_coeffs = gr.firdes.low_pass(
            1.0,  # gain
            sw_decim * self._samples_per_symbol,  # sampling rate
            1.0,  # midpoint of trans. band
            0.5,  # width of trans. band
            gr.firdes.WIN_HANN,
        )  # filter type
        self.channel_filter = gr.fft_filter_ccc(sw_decim, chan_coeffs)

        # receiver
        self.packet_receiver = blks22.demod_pkts(
            self._demod_class(**demod_kwargs), access_code=None, callback=self._rx_callback, threshold=-1
        )

        # Carrier Sensing Blocks
        alpha = 0.001
        thresh = 30  # in dB, will have to adjust
        self.probe = gr.probe_avg_mag_sqrd_c(thresh, alpha)

        # Display some information about the setup
        if self._verbose:
            self._print_verbage()

        # connect block input to channel filter
        self.connect(self, self.channel_filter)

        # connect the channel input filter to the carrier power detector
        self.connect(self.channel_filter, self.probe)

        # connect channel filter to the packet receiver
        self.connect(self.channel_filter, self.packet_receiver)
예제 #11
0
    def __init__(self, fft_length, occupied_tones, carrier_map_bin):
        
        """
        Hierarchical block for receiving OFDM symbols.
        """
        gr.hier_block2.__init__(self, "ncofdm_filt",
                                gr.io_signature(1, 1, gr.sizeof_gr_complex),
                                gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Input signature

        # fft length, e.g. 256
        self._fft_length = fft_length
        # the number of used subcarriers, e.g. 240
        self._occupied_tones = occupied_tones
        # a binary array indicates the used subcarriers
        self._carrier_map_bin = carrier_map_bin

        # setup filter banks
        self.chan_filt_low = gr.fft_filter_ccc(1,[1]) 
        self.chan_filt_high1 = gr.fft_filter_ccc(1,[1]) 
        self.chan_filt_high2 = gr.fft_filter_ccc(1,[1])
        self.chan_filt_high3 = gr.fft_filter_ccc(1,[1])
        self.chan_filt_high4 = gr.fft_filter_ccc(1,[1])
        self.chan_filt_high5 = gr.fft_filter_ccc(1,[1])
        
        # calculate the filter taps
        filt_num = self.calc_filter_taps(2, 0)
        

        # signals run into a serial of filters, one lowpass filter and 5 highpass filters
        self.connect(self, self.chan_filt_high1,
                           self.chan_filt_high2, self.chan_filt_high3,
                           self.chan_filt_high4, self.chan_filt_high5,
                           self.chan_filt_low, self) 
 def test_ccc_001(self):
     src_data = (0,1,2,3,4,5,6,7)
     taps = (1,)
     expected_result = tuple([complex(x) for x in (0,1,2,3,4,5,6,7)])
     src = gr.vector_source_c(src_data)
     op = gr.fft_filter_ccc(1, taps)
     dst = gr.vector_sink_c()
     self.fg.connect(src, op, dst)
     self.fg.run()
     result_data = dst.data()
     #print 'expected:', expected_result
     #print 'results: ', result_data
     self.assertComplexTuplesAlmostEqual (expected_result, result_data, 5)
예제 #13
0
    def test_ccc_001(self):
	tb = gr.top_block()
        src_data = (0,1,2,3,4,5,6,7)
        taps = (1,)
        expected_result = tuple([complex(x) for x in (0,1,2,3,4,5,6,7)])
        src = gr.vector_source_c(src_data)
        op = gr.fft_filter_ccc(1, taps)
        dst = gr.vector_sink_c()
        tb.connect(src, op, dst)
        tb.run()
        result_data = dst.data()
        #print 'expected:', expected_result
        #print 'results: ', result_data
        self.assertComplexTuplesAlmostEqual (expected_result, result_data, 5)
예제 #14
0
    def test_ccc_002(self):
        # Test nthreads
	tb = gr.top_block()
        src_data = (0,1,2,3,4,5,6,7)
        taps = (2,)
        nthreads = 2
        expected_result = tuple([2 * complex(x) for x in (0,1,2,3,4,5,6,7)])
        src = gr.vector_source_c(src_data)
        op = gr.fft_filter_ccc(1, taps, nthreads)
        dst = gr.vector_sink_c()
        tb.connect(src, op, dst)
        tb.run()
        result_data = dst.data()
        #print 'expected:', expected_result
        #print 'results: ', result_data
        self.assertComplexTuplesAlmostEqual (expected_result, result_data, 5)
예제 #15
0
    def __init__(self, mpoints, taps=None):
        """
        Takes 1 complex stream in, produces M complex streams out
        that runs at 1/M times the input sample rate

        @param mpoints: number of freq bins/interpolation factor/subbands
        @param taps:    filter taps for subband filter

        Same channel to frequency mapping as described above.
        """
        item_size = gr.sizeof_gr_complex
        gr.hier_block2.__init__(
            self,
            "analysis_filterbank",
            gr.io_signature(1, 1, item_size),  # Input signature
            gr.io_signature(mpoints, mpoints, item_size),
        )  # Output signature

        if taps is None:
            taps = _generate_synthesis_taps(mpoints)

        # pad taps to multiple of mpoints
        r = len(taps) % mpoints
        if r != 0:
            taps = taps + (mpoints - r) * (0,)

        # split in mpoints separate set of taps
        sub_taps = _split_taps(taps, mpoints)

        # print >> sys.stderr, "mpoints =", mpoints, "len(sub_taps) =", len(sub_taps)

        self.s2ss = gr.stream_to_streams(item_size, mpoints)
        # filters here
        self.ss2v = gr.streams_to_vector(item_size, mpoints)
        self.fft = gr.fft_vcc(mpoints, True, [])
        self.v2ss = gr.vector_to_streams(item_size, mpoints)

        self.connect(self, self.s2ss)

        # build mpoints fir filters...
        for i in range(mpoints):
            f = gr.fft_filter_ccc(1, sub_taps[mpoints - i - 1])
            self.connect((self.s2ss, i), f)
            self.connect(f, (self.ss2v, i))
            self.connect((self.v2ss, i), (self, i))

        self.connect(self.ss2v, self.fft, self.v2ss)
예제 #16
0
    def __init__(self, mpoints, taps=None):
        """
        Takes 1 complex stream in, produces M complex streams out
        that runs at 1/M times the input sample rate

        @param mpoints: number of freq bins/interpolation factor/subbands
        @param taps:    filter taps for subband filter

        Same channel to frequency mapping as described above.
        """
        item_size = gr.sizeof_gr_complex
        gr.hier_block2.__init__(
            self,
            "analysis_filterbank",
            gr.io_signature(1, 1, item_size),  # Input signature
            gr.io_signature(mpoints, mpoints, item_size))  # Output signature

        if taps is None:
            taps = _generate_synthesis_taps(mpoints)

        # pad taps to multiple of mpoints
        r = len(taps) % mpoints
        if r != 0:
            taps = taps + (mpoints - r) * (0, )

        # split in mpoints separate set of taps
        sub_taps = _split_taps(taps, mpoints)

        # print >> sys.stderr, "mpoints =", mpoints, "len(sub_taps) =", len(sub_taps)

        self.s2ss = gr.stream_to_streams(item_size, mpoints)
        # filters here
        self.ss2v = gr.streams_to_vector(item_size, mpoints)
        self.fft = gr.fft_vcc(mpoints, True, [])
        self.v2ss = gr.vector_to_streams(item_size, mpoints)

        self.connect(self, self.s2ss)

        # build mpoints fir filters...
        for i in range(mpoints):
            f = gr.fft_filter_ccc(1, sub_taps[mpoints - i - 1])
            self.connect((self.s2ss, i), f)
            self.connect(f, (self.ss2v, i))
            self.connect((self.v2ss, i), (self, i))

        self.connect(self.ss2v, self.fft, self.v2ss)
    def test_ccc_004(self):
        random.seed(0)
        for i in xrange(25):
            # sys.stderr.write("\n>>> Loop = %d\n" % (i,))
            src_len = 4*1024
            src_data = make_random_complex_tuple(src_len)
            ntaps = int(random.uniform(2, 1000))
            taps = make_random_complex_tuple(ntaps)
            expected_result = reference_filter_ccc(1, taps, src_data)

            src = gr.vector_source_c(src_data)
            op = gr.fft_filter_ccc(1, taps)
            dst = gr.vector_sink_c()
            self.fg.connect(src, op, dst)
            self.fg.run()
            result_data = dst.data()

            self.assert_fft_ok2(expected_result, result_data)
예제 #18
0
 def __init__(self, center_freq, bandwidth, samp_rate):
     gr.hier_block2.__init__(self, "linker",
                             gr.io_signature(1, 1, gr.sizeof_gr_complex),
                             gr.io_signature(1, 1, gr.sizeof_gr_complex))
     self.coswave = gr.sig_source_c(samp_rate, gr.GR_COS_WAVE,
                                    -center_freq, 1, 0)
     self.multiply = gr.multiply_vcc(1)
     midpoint = bandwidth
     width = 20
     stopband_attenuation = 10
     decim = int(samp_rate / bandwidth / 4)
     taps = gr.firdes.low_pass_2(decim, samp_rate, midpoint, width,
                                 stopband_attenuation)
     self.lpf = gr.fft_filter_ccc(decim, taps)
     self.connect(self, (self.multiply, 0))
     self.connect(self.coswave, (self.multiply, 1))
     self.connect(self.multiply, self.lpf, self)
     self.samp_rate = 1.0*samp_rate/decim
예제 #19
0
    def test_ccc_004(self):
        random.seed(0)
        for i in xrange(25):
            # sys.stderr.write("\n>>> Loop = %d\n" % (i,))
            src_len = 4*1024
            src_data = make_random_complex_tuple(src_len)
            ntaps = int(random.uniform(2, 1000))
            taps = make_random_complex_tuple(ntaps)
            expected_result = reference_filter_ccc(1, taps, src_data)

            src = gr.vector_source_c(src_data)
            op = gr.fft_filter_ccc(1, taps)
            dst = gr.vector_sink_c()
	    tb = gr.top_block()
            tb.connect(src, op, dst)
            tb.run()
            result_data = dst.data()
	    del tb

            self.assert_fft_ok2(expected_result, result_data)
예제 #20
0
    def test_ccc_006(self):
        # Test decimating with nthreads=2
        random.seed(0)
        nthreads = 2
        for i in xrange(25):
            # sys.stderr.write("\n>>> Loop = %d\n" % (i,))
            dec = i + 1
            src_len = 4*1024
            src_data = make_random_complex_tuple(src_len)
            ntaps = int(random.uniform(2, 100))
            taps = make_random_complex_tuple(ntaps)
            expected_result = reference_filter_ccc(dec, taps, src_data)

            src = gr.vector_source_c(src_data)
            op = gr.fft_filter_ccc(dec, taps, nthreads)
            dst = gr.vector_sink_c()
            tb = gr.top_block()
	    tb.connect(src, op, dst)
            tb.run()
            del tb
	    result_data = dst.data()

            self.assert_fft_ok2(expected_result, result_data)
예제 #21
0
    def __init__(self, fft_length, cp_length, logging=False):
        """
        OFDM synchronization using PN Correlation:
        T. M. Schmidl and D. C. Cox, "Robust Frequency and Timing
        Synchonization for OFDM," IEEE Trans. Communications, vol. 45,
        no. 12, 1997.
        """
        
	gr.hier_block2.__init__(self, "ofdm_sync_pn",
				gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
                                gr.io_signature2(2, 2, gr.sizeof_float, gr.sizeof_char)) # Output signature

        self.input = gr.add_const_cc(0)

        # PN Sync

        # Create a delay line
        self.delay = gr.delay(gr.sizeof_gr_complex, fft_length/2)

        # Correlation from ML Sync
        self.conjg = gr.conjugate_cc();
        self.corr = gr.multiply_cc();

        # Create a moving sum filter for the corr output
        if 1:
            moving_sum_taps = [1.0 for i in range(fft_length//2)]
            self.moving_sum_filter = gr.fir_filter_ccf(1,moving_sum_taps)
        else:
            moving_sum_taps = [complex(1.0,0.0) for i in range(fft_length//2)]
            self.moving_sum_filter = gr.fft_filter_ccc(1,moving_sum_taps)

        # Create a moving sum filter for the input
        self.inputmag2 = gr.complex_to_mag_squared()
        movingsum2_taps = [1.0 for i in range(fft_length//2)]

        if 1:
            self.inputmovingsum = gr.fir_filter_fff(1,movingsum2_taps)
        else:
            self.inputmovingsum = gr.fft_filter_fff(1,movingsum2_taps)

        self.square = gr.multiply_ff()
        self.normalize = gr.divide_ff()
     
        # Get magnitude (peaks) and angle (phase/freq error)
        self.c2mag = gr.complex_to_mag_squared()
        self.angle = gr.complex_to_arg()

        self.sample_and_hold = gr.sample_and_hold_ff()

        #ML measurements input to sampler block and detect
        #self.sub1 = gr.add_const_ff(-1)
        self.sub1 = gr.add_const_ff(0)
        self.pk_detect = gr.peak_detector_fb(0.20, 0.20, 30, 0.001)
        #self.pk_detect = gr.peak_detector2_fb(9)

        self.connect(self, self.input)
        
        # Calculate the frequency offset from the correlation of the preamble
        self.connect(self.input, self.delay)
        self.connect(self.input, (self.corr,0))
        self.connect(self.delay, self.conjg)
        self.connect(self.conjg, (self.corr,1))
        self.connect(self.corr, self.moving_sum_filter)
        self.connect(self.moving_sum_filter, self.c2mag)
        self.connect(self.moving_sum_filter, self.angle)
        self.connect(self.angle, (self.sample_and_hold,0))

        # Get the power of the input signal to normalize the output of the correlation
        self.connect(self.input, self.inputmag2, self.inputmovingsum)
        self.connect(self.inputmovingsum, (self.square,0))
        self.connect(self.inputmovingsum, (self.square,1))
        self.connect(self.square, (self.normalize,1))
        self.connect(self.c2mag, (self.normalize,0))

        # Create a moving sum filter for the corr output
        matched_filter_taps = [1.0/cp_length for i in range(cp_length)]
        self.matched_filter = gr.fir_filter_fff(1,matched_filter_taps)
        self.connect(self.normalize, self.matched_filter)
        
        self.connect(self.matched_filter, self.sub1, self.pk_detect)
        #self.connect(self.matched_filter, self.pk_detect)
        self.connect(self.pk_detect, (self.sample_and_hold,1))

        # Set output signals
        #    Output 0: fine frequency correction value
        #    Output 1: timing signal
        self.connect(self.sample_and_hold, (self,0))
        self.connect(self.pk_detect, (self,1))

        if logging:
            self.connect(self.matched_filter, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-mf_f.dat"))
            self.connect(self.normalize, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-theta_f.dat"))
            self.connect(self.angle, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-epsilon_f.dat"))
            self.connect(self.pk_detect, gr.file_sink(gr.sizeof_char, "ofdm_sync_pn-peaks_b.dat"))
            self.connect(self.sample_and_hold, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-sample_and_hold_f.dat"))
            self.connect(self.input, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_pn-input_c.dat"))
예제 #22
0
    def __init__(self, bandwidth, fft_length, cp_length, occupied_tones, snr, ks, logging=False, mode='benchmark'):
        """
	Hierarchical block for receiving OFDM symbols.

	The input is the complex modulated signal at baseband.
        Synchronized packets are sent back to the demodulator.

        @param fft_length: total number of subcarriers
        @type  fft_length: int
        @param cp_length: length of cyclic prefix as specified in subcarriers (<= fft_length)
        @type  cp_length: int
        @param occupied_tones: number of subcarriers used for data
        @type  occupied_tones: int
        @param snr: estimated signal to noise ratio used to guide cyclic prefix synchronizer
        @type  snr: float
        @param ks: known symbols used as preambles to each packet
        @type  ks: list of lists
        @param logging: turn file logging on or off
        @type  logging: bool
	"""

	gr.hier_block2.__init__(self, "ofdm_receiver",
				gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
                                gr.io_signature2(2, 2, gr.sizeof_gr_complex*occupied_tones, gr.sizeof_char)) # Output signature
        
        bw = (float(occupied_tones) / float(fft_length)) / 2.0
        tb = bw*0.08
        chan_coeffs = gr.firdes.low_pass (1.0,                     # gain
                                          1.0,                     # sampling rate
                                          bw+tb,                   # midpoint of trans. band
                                          tb,                      # width of trans. band
                                          gr.firdes.WIN_HAMMING)   # filter type
        self.chan_filt = gr.fft_filter_ccc(1, chan_coeffs)
        
        win = [1 for i in range(fft_length)]

        zeros_on_left = int(math.ceil((fft_length - occupied_tones)/2.0))
        ks0 = fft_length*[0,]
        ks0[zeros_on_left : zeros_on_left + occupied_tones] = ks[0]
        
        ks0 = fft.ifftshift(ks0)
        ks0time = fft.ifft(ks0)
        # ADD SCALING FACTOR
        ks0time = ks0time.tolist()

        SYNC = "pn"
        if SYNC == "ml":
            nco_sensitivity = -1.0/fft_length   # correct for fine frequency
            self.ofdm_sync = ofdm_sync_ml(fft_length,
                                          cp_length,
                                          snr,
                                          ks0time,
                                          logging)
        elif SYNC == "pn":
            nco_sensitivity = -2.0/fft_length   # correct for fine frequency
            self.ofdm_sync = ofdm_sync_pn(fft_length,
                                          cp_length,
                                          logging, mode)
        elif SYNC == "pnac":
            nco_sensitivity = -2.0/fft_length   # correct for fine frequency
            self.ofdm_sync = ofdm_sync_pnac(fft_length,
                                            cp_length,
                                            ks0time,
                                            logging)
        # for testing only; do not user over the air
        # remove filter and filter delay for this
        elif SYNC == "fixed":
            self.chan_filt = gr.multiply_const_cc(1.0) 
            nsymbols = 18      # enter the number of symbols per packet
            freq_offset = 0.0  # if you use a frequency offset, enter it here
            nco_sensitivity = -2.0/fft_length   # correct for fine frequency
            self.ofdm_sync = ofdm_sync_fixed(fft_length,
                                             cp_length,
                                             nsymbols,
                                             freq_offset,
                                             logging)

        # Set up blocks

        self.nco = gr.frequency_modulator_fc(nco_sensitivity)         # generate a signal proportional to frequency error of sync block
        self.sigmix = gr.multiply_cc()
        self.sampler = digital_swig.ofdm_sampler(fft_length, fft_length+cp_length, long(bandwidth))
        self.fft_demod = gr.fft_vcc(fft_length, True, win, True)
        self.ofdm_frame_acq = digital_swig.ofdm_frame_acquisition(occupied_tones,
                                                                  fft_length,
                                                                  cp_length, ks[0])

        self.connect(self, self.chan_filt)                            # filter the input channel
        self.connect(self.chan_filt, self.ofdm_sync)                  # into the synchronization alg.
        self.connect((self.ofdm_sync,0), self.nco, (self.sigmix,1))   # use sync freq. offset output to derotate input signal
        self.connect(self.chan_filt, (self.sigmix,0))                 # signal to be derotated
        self.connect(self.sigmix, (self.sampler,0))                   # sample off timing signal detected in sync alg
        self.connect((self.ofdm_sync,1), (self.sampler,1))            # timing signal to sample at

        self.connect((self.sampler,0), self.fft_demod)                # send derotated sampled signal to FFT
        self.connect(self.fft_demod, (self.ofdm_frame_acq,0))         # find frame start and equalize signal
        self.connect((self.sampler,1), (self.ofdm_frame_acq,1))       # send timing signal to signal frame start
        self.connect((self.ofdm_frame_acq,0), (self,0))               # finished with fine/coarse freq correction,
        self.connect((self.ofdm_frame_acq,1), (self,1))               # frame and symbol timing, and equalization

        # for debugging
        self.connect(self.chan_filt, gr.file_sink(gr.sizeof_gr_complex, "ofdm_receiver-chan_filt_c.dat"))

        if logging:
            self.connect(self.chan_filt, gr.file_sink(gr.sizeof_gr_complex, "ofdm_receiver-chan_filt_c.dat"))
            self.connect(self.fft_demod, gr.file_sink(gr.sizeof_gr_complex*fft_length, "ofdm_receiver-fft_out_c.dat"))
            self.connect(self.ofdm_frame_acq,
                         gr.file_sink(gr.sizeof_gr_complex*occupied_tones, "ofdm_receiver-frame_acq_c.dat"))
            self.connect((self.ofdm_frame_acq,1), gr.file_sink(1, "ofdm_receiver-found_corr_b.dat"))
            self.connect(self.sampler, gr.file_sink(gr.sizeof_gr_complex*fft_length, "ofdm_receiver-sampler_c.dat"))
            self.connect(self.sigmix, gr.file_sink(gr.sizeof_gr_complex, "ofdm_receiver-sigmix_c.dat"))
            self.connect(self.nco, gr.file_sink(gr.sizeof_gr_complex, "ofdm_receiver-nco_c.dat"))
예제 #23
0
    def __init__(self, fft_length, cp_length, logging=False):
        """
        OFDM synchronization using PN Correlation:
        T. M. Schmidl and D. C. Cox, "Robust Frequency and Timing
        Synchonization for OFDM," IEEE Trans. Communications, vol. 45,
        no. 12, 1997.
        """
        
	gr.hier_block2.__init__(self, "ofdm_sync_pn",
				gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
                                gr.io_signature2(2, 2, gr.sizeof_float, gr.sizeof_char)) # Output signature

        self.input = gr.add_const_cc(0)

        # PN Sync

        # Create a delay line
        self.delay = gr.delay(gr.sizeof_gr_complex, fft_length/2)

        # Correlation from ML Sync
        self.conjg = gr.conjugate_cc();
        self.corr = gr.multiply_cc();

        # Create a moving sum filter for the corr output
        if 1:
            moving_sum_taps = [1.0 for i in range(fft_length//2)]
            self.moving_sum_filter = gr.fir_filter_ccf(1,moving_sum_taps)
        else:
            moving_sum_taps = [complex(1.0,0.0) for i in range(fft_length//2)]
            self.moving_sum_filter = gr.fft_filter_ccc(1,moving_sum_taps)

        # Create a moving sum filter for the input
        self.inputmag2 = gr.complex_to_mag_squared()

        # Modified by Yong (12.06.27)
        #movingsum2_taps = [1.0 for i in range(fft_length//2)]
        movingsum2_taps = [0.5 for i in range(fft_length)]

        if 1:
            self.inputmovingsum = gr.fir_filter_fff(1,movingsum2_taps)
        else:
            self.inputmovingsum = gr.fft_filter_fff(1,movingsum2_taps)

        self.square = gr.multiply_ff()
        self.normalize = gr.divide_ff()
     
        # Get magnitude (peaks) and angle (phase/freq error)
        self.c2mag = gr.complex_to_mag_squared()
        self.angle = gr.complex_to_arg()

        self.sample_and_hold = gr.sample_and_hold_ff()

        #ML measurements input to sampler block and detect
        self.sub1 = gr.add_const_ff(-1)
        self.pk_detect = gr.peak_detector_fb(0.20, 0.20, 30, 0.001)
        #self.pk_detect = gr.peak_detector2_fb(9)

        self.connect(self, self.input)
        
        # Calculate the frequency offset from the correlation of the preamble
        self.connect(self.input, self.delay)
        self.connect(self.input, (self.corr,0))
        self.connect(self.delay, self.conjg)
        self.connect(self.conjg, (self.corr,1))
        self.connect(self.corr, self.moving_sum_filter)
        self.connect(self.moving_sum_filter, self.c2mag)
        self.connect(self.moving_sum_filter, self.angle)
        self.connect(self.angle, (self.sample_and_hold,0))

        # Get the power of the input signal to normalize the output of the correlation
        self.connect(self.input, self.inputmag2, self.inputmovingsum)
        self.connect(self.inputmovingsum, (self.square,0))
        self.connect(self.inputmovingsum, (self.square,1))
        self.connect(self.square, (self.normalize,1))
        self.connect(self.c2mag, (self.normalize,0))

        # Create a moving sum filter for the corr output
        matched_filter_taps = [1.0/cp_length for i in range(cp_length)]
        self.matched_filter = gr.fir_filter_fff(1,matched_filter_taps)
        self.connect(self.normalize, self.matched_filter)
        
        self.connect(self.matched_filter, self.sub1, self.pk_detect)
        #self.connect(self.matched_filter, self.pk_detect)
        self.connect(self.pk_detect, (self.sample_and_hold,1))

        # Set output signals
        #    Output 0: fine frequency correction value
        #    Output 1: timing signal
        self.connect(self.sample_and_hold, (self,0))
        self.connect(self.pk_detect, (self,1))

        if logging:
            self.connect(self.matched_filter, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-mf_f.dat"))
            self.connect(self.c2mag, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-nominator_f.dat"))
            self.connect(self.square, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-denominator_f.dat"))
            self.connect(self.normalize, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-theta_f.dat"))
            self.connect(self.angle, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-epsilon_f.dat"))
            self.connect(self.pk_detect, gr.file_sink(gr.sizeof_char, "ofdm_sync_pn-peaks_b.dat"))
            self.connect(self.sample_and_hold, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-sample_and_hold_f.dat"))
            self.connect(self.input, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_pn-input_c.dat"))
예제 #24
0
    def __init__(self, options):
        gr.top_block.__init__(self)

        options = copy.copy(options)
        symbol_rate = 2500000

 
 
        print "%f" % (options.tx_freq-1.25e6)
        #print "==========================================\n"
        #print "Samp per sym = %d\n" % options.samples_per_symbol
        #print "==========================================\n"

        self.source = uhd_receiver(options.args, symbol_rate, 
                                   1, #options.samples_per_symbol,
                                   options.tx_freq-1.25e6, 30,
                                   options.spec, options.antenna,
                                   options.verbose)

        low_pass_taps = [
	    -0.0401,
	    0.0663,
	    0.0468,
	    -0.0235,
	    -0.0222,
	    0.0572,
	    0.0299,
	    -0.1001,
	    -0.0294,
	    0.3166,
	    0.5302,
	    0.3166,
	    -0.0294,
	    -0.1001,
	    0.0299,
	    0.0572,
	    -0.0222,
	    -0.0235,
	    0.0468,
	    0.0663,
	    -0.0401]

	high_pass_taps = [
	    -0.0389,
	    -0.0026,
	    0.0302,
	    0.0181,
	    -0.0357,
	    -0.0394,
	    0.0450,
	    0.0923,
	    -0.0472,
	    -0.3119,
	    0.5512,
	    -0.3119,
	    -0.0472,
	    0.0923,
	    0.0450,
	    -0.0394,
	    -0.0357,
	    0.0181,
	    0.0302,
	    -0.0026,
	    -0.0389]

        # Carrier Sensing Blocks
        alpha = 0.5
        thresh = 30   # in dB, will have to adjust
        self.probe_lp = gr.probe_avg_mag_sqrd_c(thresh,alpha)
        self.probe_hp = gr.probe_avg_mag_sqrd_c(thresh,alpha)

        self.lp = gr.fft_filter_ccc(32, low_pass_taps)
        self.hp = gr.fft_filter_ccc(32, high_pass_taps)

        self.connect(self.source, self.lp)
        self.connect(self.lp, self.probe_lp)

        self.connect(self.source, self.hp)
        self.connect(self.hp, self.probe_hp)
예제 #25
0
    def __init__(self, frame, panel, vbox, argv):
        stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv)

        self.frame = frame
        self.panel = panel

        parser = OptionParser(option_class=eng_option)
        parser.add_option("-R",
                          "--rx-subdev-spec",
                          type="subdev",
                          default=(0, 0),
                          help="select USRP Rx side A or B (default=A)")
        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("-Q",
                          "--observing",
                          type="eng_float",
                          default=0.0,
                          help="set observing frequency to FREQ")
        parser.add_option("-a",
                          "--avg",
                          type="eng_float",
                          default=1.0,
                          help="set spectral averaging alpha")
        parser.add_option("-V",
                          "--favg",
                          type="eng_float",
                          default=2.0,
                          help="set folder averaging alpha")
        parser.add_option("-g",
                          "--gain",
                          type="eng_float",
                          default=None,
                          help="set gain in dB (default is midpoint)")
        parser.add_option("-l",
                          "--reflevel",
                          type="eng_float",
                          default=30.0,
                          help="Set pulse display reference level")
        parser.add_option("-L",
                          "--lowest",
                          type="eng_float",
                          default=1.5,
                          help="Lowest valid frequency bin")
        parser.add_option("-e",
                          "--longitude",
                          type="eng_float",
                          default=-76.02,
                          help="Set Observer Longitude")
        parser.add_option("-c",
                          "--latitude",
                          type="eng_float",
                          default=44.85,
                          help="Set Observer Latitude")
        parser.add_option("-F",
                          "--fft_size",
                          type="eng_float",
                          default=1024,
                          help="Size of FFT")

        parser.add_option("-t",
                          "--threshold",
                          type="eng_float",
                          default=2.5,
                          help="pulsar threshold")
        parser.add_option("-p",
                          "--lowpass",
                          type="eng_float",
                          default=100,
                          help="Pulse spectra cutoff freq")
        parser.add_option("-P", "--prefix", default="./", help="File prefix")
        parser.add_option("-u",
                          "--pulsefreq",
                          type="eng_float",
                          default=0.748,
                          help="Observation pulse rate")
        parser.add_option("-D",
                          "--dm",
                          type="eng_float",
                          default=1.0e-5,
                          help="Dispersion Measure")
        parser.add_option("-O",
                          "--doppler",
                          type="eng_float",
                          default=1.0,
                          help="Doppler ratio")
        parser.add_option("-B",
                          "--divbase",
                          type="eng_float",
                          default=20,
                          help="Y/Div menu base")
        parser.add_option("-I",
                          "--division",
                          type="eng_float",
                          default=100,
                          help="Y/Div")
        parser.add_option("-A",
                          "--audio_source",
                          default="plughw:0,0",
                          help="Audio input device spec")
        parser.add_option("-N",
                          "--num_pulses",
                          default=1,
                          type="eng_float",
                          help="Number of display pulses")
        (options, args) = parser.parse_args()
        if len(args) != 0:
            parser.print_help()
            sys.exit(1)

        self.show_debug_info = True

        self.reflevel = options.reflevel
        self.divbase = options.divbase
        self.division = options.division
        self.audiodev = options.audio_source
        self.mult = int(options.num_pulses)

        # Low-pass cutoff for post-detector filter
        # Set to 100Hz usually, since lots of pulsars fit in this
        #   range
        self.lowpass = options.lowpass

        # What is lowest valid frequency bin in post-detector FFT?
        # There's some pollution very close to DC
        self.lowest_freq = options.lowest

        # What (dB) threshold to use in determining spectral candidates
        self.threshold = options.threshold

        # Filename prefix for recording file
        self.prefix = options.prefix

        # Dispersion Measure (DM)
        self.dm = options.dm

        # Doppler shift, as a ratio
        #  1.0 == no doppler shift
        #  1.005 == a little negative shift
        #  0.995 == a little positive shift
        self.doppler = options.doppler

        #
        # Input frequency and observing frequency--not necessarily the
        #   same thing, if we're looking at the IF of some downconverter
        #   that's ahead of the USRP and daughtercard.  This distinction
        #   is important in computing the correct de-dispersion filter.
        #
        self.frequency = options.freq
        if options.observing <= 0:
            self.observing_freq = options.freq
        else:
            self.observing_freq = options.observing

        # build the graph
        self.u = usrp.source_c(decim_rate=options.decim)
        self.u.set_mux(
            usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))

        #
        # Recording file, in case we ever need to record baseband data
        #
        self.recording = gr.file_sink(gr.sizeof_char, "/dev/null")
        self.recording_state = False

        self.pulse_recording = gr.file_sink(gr.sizeof_short, "/dev/null")
        self.pulse_recording_state = False

        #
        # We come up with recording turned off, but the user may
        #  request recording later on
        self.recording.close()
        self.pulse_recording.close()

        #
        # Need these two for converting 12-bit baseband signals to 8-bit
        #
        self.tofloat = gr.complex_to_float()
        self.tochar = gr.float_to_char()

        # Need this for recording pulses (post-detector)
        self.toshort = gr.float_to_short()

        #
        # The spectral measurer sets this when it has a valid
        #   average spectral peak-to-peak distance
        # We can then use this to program the parameters for the epoch folder
        #
        # We set a sentimental value here
        self.pulse_freq = options.pulsefreq

        # Folder runs at this raw sample rate
        self.folder_input_rate = 20000

        # Each pulse in the epoch folder is sampled at 128 times the nominal
        #  pulse rate
        self.folding = 128

        #
        # Try to find candidate parameters for rational resampler
        #
        save_i = 0
        candidates = []
        for i in range(20, 300):
            input_rate = self.folder_input_rate
            output_rate = int(self.pulse_freq * i)
            interp = gru.lcm(input_rate, output_rate) / input_rate
            decim = gru.lcm(input_rate, output_rate) / output_rate
            if (interp < 500 and decim < 250000):
                candidates.append(i)

        # We didn't find anything, bail!
        if (len(candidates) < 1):
            print "Couldn't converge on resampler parameters"
            sys.exit(1)

        #
        # Now try to find candidate with the least sampling error
        #
        mindiff = 999.999
        for i in candidates:
            diff = self.pulse_freq * i
            diff = diff - int(diff)
            if (diff < mindiff):
                mindiff = diff
                save_i = i

        # Recompute rates
        input_rate = self.folder_input_rate
        output_rate = int(self.pulse_freq * save_i)

        # Compute new interp and decim, based on best candidate
        interp = gru.lcm(input_rate, output_rate) / input_rate
        decim = gru.lcm(input_rate, output_rate) / output_rate

        # Save optimized folding parameters, used later
        self.folding = save_i
        self.interp = int(interp)
        self.decim = int(decim)

        # So that we can view N pulses in the pulse viewer window
        FOLD_MULT = self.mult

        # determine the daughterboard subdevice we're using
        self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
        self.cardtype = self.u.daughterboard_id(0)

        # Compute raw input rate
        input_rate = self.u.adc_freq() / self.u.decim_rate()

        # BW==input_rate for complex data
        self.bw = input_rate

        #
        # Set baseband filter bandwidth if DBS_RX:
        #
        if self.cardtype == usrp_dbid.DBS_RX:
            lbw = input_rate / 2
            if lbw < 1.0e6:
                lbw = 1.0e6
            self.subdev.set_bw(lbw)

        #
        # We use this as a crude volume control for the audio output
        #
        #self.volume = gr.multiply_const_ff(10**(-1))

        #
        # Create location data for ephem package
        #
        self.locality = ephem.Observer()
        self.locality.long = str(options.longitude)
        self.locality.lat = str(options.latitude)

        #
        # What is the post-detector LPF cutoff for the FFT?
        #
        PULSAR_MAX_FREQ = int(options.lowpass)

        # First low-pass filters down to input_rate/FIRST_FACTOR
        #   and decimates appropriately
        FIRST_FACTOR = int(input_rate / (self.folder_input_rate / 2))
        first_filter = gr.firdes.low_pass(1.0, input_rate,
                                          input_rate / FIRST_FACTOR,
                                          input_rate / (FIRST_FACTOR * 20),
                                          gr.firdes.WIN_HAMMING)

        # Second filter runs at the output rate of the first filter,
        #  And low-pass filters down to PULSAR_MAX_FREQ*10
        #
        second_input_rate = int(input_rate / (FIRST_FACTOR / 2))
        second_filter = gr.firdes.band_pass(1.0, second_input_rate, 0.10,
                                            PULSAR_MAX_FREQ * 10,
                                            PULSAR_MAX_FREQ * 1.5,
                                            gr.firdes.WIN_HAMMING)

        # Third filter runs at PULSAR_MAX_FREQ*20
        #   and filters down to PULSAR_MAX_FREQ
        #
        third_input_rate = PULSAR_MAX_FREQ * 20
        third_filter = gr.firdes_band_pass(1.0, third_input_rate, 0.10,
                                           PULSAR_MAX_FREQ,
                                           PULSAR_MAX_FREQ / 10.0,
                                           gr.firdes.WIN_HAMMING)

        #
        # Create the appropriate FFT scope
        #
        self.scope = ra_fftsink.ra_fft_sink_f(panel,
                                              fft_size=int(options.fft_size),
                                              sample_rate=PULSAR_MAX_FREQ * 2,
                                              title="Post-detector spectrum",
                                              ofunc=self.pulsarfunc,
                                              xydfunc=self.xydfunc,
                                              fft_rate=200)

        #
        # Tell scope we're looking from DC to PULSAR_MAX_FREQ
        #
        self.scope.set_baseband_freq(0.0)

        #
        # Setup stripchart for showing pulse profiles
        #
        hz = "%5.3fHz " % self.pulse_freq
        per = "(%5.3f sec)" % (1.0 / self.pulse_freq)
        sr = "%d sps" % (int(self.pulse_freq * self.folding))
        times = " %d Pulse Intervals" % self.mult
        self.chart = ra_stripchartsink.stripchart_sink_f(
            panel,
            sample_rate=1,
            stripsize=self.folding * FOLD_MULT,
            parallel=True,
            title="Pulse Profiles: " + hz + per + times,
            xlabel="Seconds @ " + sr,
            ylabel="Level",
            autoscale=True,
            divbase=self.divbase,
            scaling=1.0 / (self.folding * self.pulse_freq))
        self.chart.set_ref_level(self.reflevel)
        self.chart.set_y_per_div(self.division)

        # De-dispersion filter setup
        #
        # Do this here, just before creating the filter
        #  that will use the taps.
        #
        ntaps = self.compute_disp_ntaps(self.dm, self.bw, self.observing_freq)

        # Taps for the de-dispersion filter
        self.disp_taps = Numeric.zeros(ntaps, Numeric.Complex64)

        # Compute the de-dispersion filter now
        self.compute_dispfilter(self.dm, self.doppler, self.bw,
                                self.observing_freq)

        #
        # Call constructors for receive chains
        #

        #
        # Now create the FFT filter using the computed taps
        self.dispfilt = gr.fft_filter_ccc(1, self.disp_taps)

        #
        # Audio sink
        #
        #print "input_rate ", second_input_rate, "audiodev ", self.audiodev
        #self.audio = audio.sink(second_input_rate, self.audiodev)

        #
        # The three post-detector filters
        # Done this way to allow an audio path (up to 10Khz)
        # ...and also because going from xMhz down to ~100Hz
        # In a single filter doesn't seem to work.
        #
        self.first = gr.fir_filter_fff(FIRST_FACTOR / 2, first_filter)

        p = second_input_rate / (PULSAR_MAX_FREQ * 20)
        self.second = gr.fir_filter_fff(int(p), second_filter)
        self.third = gr.fir_filter_fff(10, third_filter)

        # Detector
        self.detector = gr.complex_to_mag_squared()

        self.enable_comb_filter = False
        # Epoch folder comb filter
        if self.enable_comb_filter == True:
            bogtaps = Numeric.zeros(512, Numeric.Float64)
            self.folder_comb = gr.fft_filter_ccc(1, bogtaps)

        # Rational resampler
        self.folder_rr = blks2.rational_resampler_fff(self.interp, self.decim)

        # Epoch folder bandpass
        bogtaps = Numeric.zeros(1, Numeric.Float64)
        self.folder_bandpass = gr.fir_filter_fff(1, bogtaps)

        # Epoch folder F2C/C2F
        self.folder_f2c = gr.float_to_complex()
        self.folder_c2f = gr.complex_to_float()

        # Epoch folder S2P
        self.folder_s2p = gr.serial_to_parallel(gr.sizeof_float,
                                                self.folding * FOLD_MULT)

        # Epoch folder IIR Filter (produces average pulse profiles)
        self.folder_iir = gr.single_pole_iir_filter_ff(
            1.0 / options.favg, self.folding * FOLD_MULT)

        #
        # Set all the epoch-folder goop up
        #
        self.set_folding_params()

        #
        # Start connecting configured modules in the receive chain
        #

        # Connect raw USRP to de-dispersion filter, detector
        self.connect(self.u, self.dispfilt, self.detector)

        # Connect detector output to FIR LPF
        #  in two stages, followed by the FFT scope
        self.connect(self.detector, self.first, self.second, self.third,
                     self.scope)

        # Connect audio output
        #self.connect(self.first, self.volume)
        #self.connect(self.volume, (self.audio, 0))
        #self.connect(self.volume, (self.audio, 1))

        # Connect epoch folder
        if self.enable_comb_filter == True:
            self.connect(self.first, self.folder_bandpass, self.folder_rr,
                         self.folder_f2c, self.folder_comb, self.folder_c2f,
                         self.folder_s2p, self.folder_iir, self.chart)

        else:
            self.connect(self.first, self.folder_bandpass, self.folder_rr,
                         self.folder_s2p, self.folder_iir, self.chart)

        # Connect baseband recording file (initially /dev/null)
        self.connect(self.u, self.tofloat, self.tochar, self.recording)

        # Connect pulse recording file (initially /dev/null)
        self.connect(self.first, self.toshort, self.pulse_recording)

        #
        # Build the GUI elements
        #
        self._build_gui(vbox)

        # Make GUI agree with command-line
        self.myform['average'].set_value(int(options.avg))
        self.myform['foldavg'].set_value(int(options.favg))

        # Make spectral averager agree with command line
        if options.avg != 1.0:
            self.scope.set_avg_alpha(float(1.0 / options.avg))
            self.scope.set_average(True)

        # set initial values

        if options.gain is None:
            # if no gain was specified, use the mid-point in dB
            g = self.subdev.gain_range()
            options.gain = float(g[0] + g[1]) / 2

        if options.freq is None:
            # if no freq was specified, use the mid-point
            r = self.subdev.freq_range()
            options.freq = float(r[0] + r[1]) / 2

        self.set_gain(options.gain)
        #self.set_volume(-10.0)

        if not (self.set_freq(options.freq)):
            self._set_status_msg("Failed to set initial frequency")

        self.myform['decim'].set_value(self.u.decim_rate())
        self.myform['fs@usb'].set_value(self.u.adc_freq() /
                                        self.u.decim_rate())
        self.myform['dbname'].set_value(self.subdev.name())
        self.myform['DM'].set_value(self.dm)
        self.myform['Doppler'].set_value(self.doppler)

        #
        # Start the timer that shows current LMST on the GUI
        #
        self.lmst_timer.Start(1000)
예제 #26
0
    def __init__(self,
                 fft_length,
                 cp_length,
                 kstime,
                 threshold,
                 threshold_type,
                 threshold_gap,
                 logging=False):
        """
        OFDM synchronization using PN Correlation:
        T. M. Schmidl and D. C. Cox, "Robust Frequency and Timing
        Synchonization for OFDM," IEEE Trans. Communications, vol. 45,
        no. 12, 1997.
        """

        gr.hier_block2.__init__(
            self,
            "ofdm_sync_pn",
            gr.io_signature(1, 1, gr.sizeof_gr_complex),  # Input signature
            gr.io_signature2(2, 2, gr.sizeof_float,
                             gr.sizeof_char))  # Output signature

        self.input = gr.add_const_cc(0)

        # PN Sync

        # Create a delay line
        self.delay = gr.delay(gr.sizeof_gr_complex, fft_length / 2)

        # Correlation from ML Sync
        self.conjg = gr.conjugate_cc()
        self.corr = gr.multiply_cc()

        # Create a moving sum filter for the corr output
        if 1:
            moving_sum_taps = [1.0 for i in range(fft_length // 2)]
            self.moving_sum_filter = gr.fir_filter_ccf(1, moving_sum_taps)
        else:
            moving_sum_taps = [
                complex(1.0, 0.0) for i in range(fft_length // 2)
            ]
            self.moving_sum_filter = gr.fft_filter_ccc(1, moving_sum_taps)

        # Create a moving sum filter for the input
        self.inputmag2 = gr.complex_to_mag_squared()
        movingsum2_taps = [1.0 for i in range(fft_length // 2)]
        #movingsum2_taps = [0.5 for i in range(fft_length*4)]		#apurv - implementing Veljo's suggestion, when pause b/w packets

        if 1:
            self.inputmovingsum = gr.fir_filter_fff(1, movingsum2_taps)
        else:
            self.inputmovingsum = gr.fft_filter_fff(1, movingsum2_taps)

        self.square = gr.multiply_ff()
        self.normalize = gr.divide_ff()

        # Get magnitude (peaks) and angle (phase/freq error)
        self.c2mag = gr.complex_to_mag_squared()
        self.angle = gr.complex_to_arg()

        self.sample_and_hold = gr.sample_and_hold_ff()

        #ML measurements input to sampler block and detect
        self.sub1 = gr.add_const_ff(-1)
        self.pk_detect = gr.peak_detector_fb(
            0.20, 0.20, 30, 0.001
        )  #apurv - implementing Veljo's suggestion, when pause b/w packets

        self.connect(self, self.input)

        # Calculate the frequency offset from the correlation of the preamble
        self.connect(self.input, self.delay)
        self.connect(self.input, (self.corr, 0))
        self.connect(self.delay, self.conjg)
        self.connect(self.conjg, (self.corr, 1))

        self.connect(self.corr, self.moving_sum_filter)
        #self.connect(self.moving_sum_filter, self.c2mag)
        self.connect(self.moving_sum_filter, self.angle)
        self.connect(self.angle, (self.sample_and_hold, 0))  # apurv--
        #self.connect(self.angle, gr.delay(gr.sizeof_float, offset), (self.sample_and_hold, 0))	#apurv++

        cross_correlate = 1
        if cross_correlate == 1:
            # cross-correlate with the known symbol
            kstime = [k.conjugate() for k in kstime]
            kstime.reverse()
            self.crosscorr_filter = gr.fir_filter_ccc(1, kstime)

            # get the magnitude #
            self.corrmag = gr.complex_to_mag_squared()

            self.f2b = gr.float_to_char()
            self.threshold_factor = threshold  #0.0012 #0.012   #0.0015
            if 0:
                self.slice = gr.threshold_ff(self.threshold_factor,
                                             self.threshold_factor, 0,
                                             fft_length)
            else:
                #thresholds = [self.threshold_factor, 9e-5]
                self.slice = gr.threshold_ff(threshold, threshold, 0,
                                             fft_length, threshold_type,
                                             threshold_gap)

            self.connect(self.input, self.crosscorr_filter, self.corrmag,
                         self.slice, self.f2b)

            # some debug dump #
            self.connect(self.corrmag,
                         gr.file_sink(gr.sizeof_float, "ofdm_corrmag.dat"))
            #self.connect(self.f2b, gr.file_sink(gr.sizeof_char, "ofdm_f2b.dat"))

        self.connect(self.f2b, (self.sample_and_hold, 1))

        # Set output signals
        #    Output 0: fine frequency correction value
        #    Output 1: timing signal
        self.connect(self.sample_and_hold, (self, 0))
        #self.connect(self.pk_detect, (self,1))									#removed
        #self.connect(self.f2b, gr.delay(gr.sizeof_char, 1), (self, 1))
        self.connect(self.f2b, (self, 1))

        if logging:
            self.connect(
                self.matched_filter,
                gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-mf_f.dat"))
            self.connect(
                self.normalize,
                gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-theta_f.dat"))
            self.connect(
                self.angle,
                gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-epsilon_f.dat"))
            self.connect(
                self.pk_detect,
                gr.file_sink(gr.sizeof_char, "ofdm_sync_pn-peaks_b.dat"))
            self.connect(
                self.sample_and_hold,
                gr.file_sink(gr.sizeof_float,
                             "ofdm_sync_pn-sample_and_hold_f.dat"))
            self.connect(
                self.input,
                gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_pn-input_c.dat"))
    def __init__(self, ntxchans, nrxchans, fft_length, cp_length, occupied_tones, snr, ks, logging=False):
        """
	Hierarchical block for receiving OFDM symbols.

	The input is the complex modulated signal at baseband.
        Synchronized packets are sent back to the demodulator.

        @param ntxchans: Number of transmitter MIMO channels (antennas)
        @type  ntxchans: int
        @param nrxchans: Number of reciever MIMO channels (antennas)
        @type  nrxchans: int
        @param fft_length: total number of subcarriers
        @type  fft_length: int
        @param cp_length: length of cyclic prefix as specified in subcarriers (<= fft_length)
        @type  cp_length: int
        @param occupied_tones: number of subcarriers used for data
        @type  occupied_tones: int
        @param snr: estimated signal to noise ratio used to guide cyclic prefix synchronizer
        @type  snr: float
        @param ks: known symbols used as preambles to each packet
        @type  ks: list of lists
        @param logging: turn file logging on or off
        @type  logging: bool
	"""

	gr.hier_block2.__init__(self, "ofdm_mimo_receiver",
				gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
                                gr.io_signature2(2, 2, gr.sizeof_gr_complex*occupied_tones, gr.sizeof_char)) # Output signature
        
        bw = (float(occupied_tones) / float(fft_length)) / 2.0
        tb = bw*0.08
        chan_coeffs = gr.firdes.low_pass (1.0,                     # gain
                                          1.0,                     # sampling rate
                                          bw+tb,                   # midpoint of trans. band
                                          tb,                      # width of trans. band
                                          gr.firdes.WIN_HAMMING)   # filter type

        # For starters, run Sync on channel 0 and use it to clock and retime all channels
        win = [1 for i in range(fft_length)]

        zeros_on_left = int(math.ceil((fft_length - occupied_tones)/2.0))
        ks0 = fft_length*[0,]
        ks0[zeros_on_left : zeros_on_left + occupied_tones] = ks[0][0:]
        
        ks0 = fft.ifftshift(ks0)
        ks0time = fft.ifft(ks0)
        # ADD SCALING FACTOR
        ks0time = ks0time.tolist()

        SYNC = "pn"
        if SYNC == "ml":
            nco_sensitivity = -1.0/fft_length                             # correct for fine frequency
            self.ofdm_sync = ofdm_sync_ml(fft_length, cp_length, snr, ks0time, logging)
        elif SYNC == "pn":
            nco_sensitivity = -2.0/fft_length                             # correct for fine frequency
            self.ofdm_sync = ofdm_sync_pn(fft_length, cp_length, logging)
        elif SYNC == "pnac":
            nco_sensitivity = -2.0/fft_length                             # correct for fine frequency
            self.ofdm_sync = ofdm_sync_pnac(fft_length, cp_length, ks0time, logging)
        elif SYNC == "fixed":                                             # for testing only; do not user over the air
            self.chan_filt = gr.multiply_const_cc(1.0)                    # remove filter and filter delay for this
            nsymbols = 18                                                 # enter the number of symbols per packet
            freq_offset = 0.0                                             # if you use a frequency offset, enter it here
            nco_sensitivity = -2.0/fft_length                             # correct for fine frequency
            self.ofdm_sync = ofdm_sync_fixed(fft_length, cp_length, nsymbols, freq_offset, logging)

        # Set up blocks
        self.chan_filt = list()
        self.sigmix = list()
        self.sampler = list()
        self.fft_demod = list()

        # Deinterleave the incoming stream into separate channels
        self.deint = gr.deinterleave(gr.sizeof_gr_complex)

        # generate a signal proportional to frequency error of sync block
        self.nco = gr.frequency_modulator_fc(nco_sensitivity)

        # Manage and combine all channels
        if 0:
            self.ofdm_frame_acq = gr.ofdm_mrc_frame_acquisition(nrxchans, occupied_tones, fft_length,
                                                                cp_length, ks[0])
        else:
            print "Transmitter using ", ntxchans
            print "Receiver using    ", nrxchans
            if(ntxchans == 1):
                self.ofdm_frame_acq = gr.ofdm_alamouti_frame_acquisition(ntxchans, occupied_tones, fft_length,
                                                                         cp_length, ks[0], occupied_tones*[0,])
            else:
                self.ofdm_frame_acq = gr.ofdm_alamouti_frame_acquisition(ntxchans, occupied_tones, fft_length,
                                                                         cp_length, ks[0], ks[1])

        self.connect(self, self.deint)               # deinterleave channels
        self.connect((self.ofdm_sync,0), self.nco)   # use sync freq. offset to derotate signal

        for i in xrange(nrxchans):
            self.chan_filt.append(gr.fft_filter_ccc(1, chan_coeffs))
            self.sigmix.append(gr.multiply_cc())
            self.sampler.append(gr.ofdm_sampler(fft_length, fft_length+cp_length))
            self.fft_demod.append(gr.fft_vcc(fft_length, True, win, True))
            

            self.connect((self.deint, i), self.chan_filt[i])              # filter the input channel
            self.connect(self.nco, (self.sigmix[i],1))                    # use sync freq. offset to derotate signal
            self.connect(self.chan_filt[i], (self.sigmix[i],0))           # signal to be derotated
            self.connect(self.sigmix[i], (self.sampler[i],0))             # sample off timing signal detected in sync alg
            self.connect((self.ofdm_sync,1), (self.sampler[i],1))         # timing signal to sample at
            
            self.connect((self.sampler[i],0), self.fft_demod[i])          # send derotated sampled signal to FFT
            self.connect(self.fft_demod[i], (self.ofdm_frame_acq,1+i))    # find frame start and equalize signal

            if logging:
                self.connect(self.chan_filt[i],
                             gr.file_sink(gr.sizeof_gr_complex, ("ofdm_mimo-receiver-chan%02d-chan_filt_c.dat" % i)))
                self.connect(self.fft_demod[i],
                             gr.file_sink(gr.sizeof_gr_complex*fft_length, ("ofdm_mimo-receiver-chan%02d-fft_out_c.dat" % i)))
                self.connect(self.sampler[i],
                             gr.file_sink(gr.sizeof_gr_complex*fft_length, ("ofdm_mimo-receiver-chan%02d-sampler_c.dat" % i)))
                self.connect(self.sigmix[i],
                             gr.file_sink(gr.sizeof_gr_complex, ("ofdm_mimo-receiver-chan%02d-sigmix_c.dat" % i)))
                
        if logging:
            self.connect((self.ofdm_frame_acq,0),
                         gr.file_sink(gr.sizeof_gr_complex*occupied_tones, "ofdm_mimo-receiver-frame_acq_c.dat"))
            self.connect((self.ofdm_frame_acq,1), gr.file_sink(1, "ofdm_mimo-receiver-found_corr_b.dat"))
            self.connect(self.nco, gr.file_sink(gr.sizeof_gr_complex, "ofdm_mimo-receiver-nco_c.dat"))
            
        self.connect(self.chan_filt[0], self.ofdm_sync)               # into the synchronization alg.
        self.connect((self.sampler[0],1), (self.ofdm_frame_acq,0))    # send timing signal to signal frame start
        self.connect((self.sampler[i],1), gr.null_sink(fft_length*gr.sizeof_char))
        self.connect((self.ofdm_frame_acq,0), (self,0))               # finished with fine/coarse freq correction,
        self.connect((self.ofdm_frame_acq,1), (self,1))               # frame and symbol timing, and equalization
예제 #28
0
=======
	#########################################
	#   Blocks
	#########################################
>>>>>>> 8d49faa84f59bbacfa1e96f9d30a844fba01f641
        # Build the demodulator
        self.demodulator = self._demod_class(**demod_kwargs)
        
        # Design filter to get actual channel we want
        sw_decim = 1
        chan_coeffs = gr.firdes.low_pass (1.0,                  # gain
                                          sw_decim * self.samples_per_symbol(), # sampling rate
                                          1.0,                  # midpoint of trans. band
                                          0.5,                  # width of trans. band
                                          gr.firdes.WIN_HANN)   # filter type
        self.channel_filter = gr.fft_filter_ccc(sw_decim, chan_coeffs)
        
        # receiver
        self.packet_receiver = \
            digital.demod_pkts(self.demodulator,
                               access_code=None,
                               callback=self._rx_callback,
                               threshold=-1)

        # Carrier Sensing Blocks
        alpha = 0.001
        thresh = 30   # in dB, will have to adjust
        self.probe = gr.probe_avg_mag_sqrd_c(thresh,alpha)

        # Display some information about the setup
        if self._verbose:
예제 #29
0
    def __init__(self, demod_class, rx_callback, options):

        gr.hier_block2.__init__(
            self,
            "receive_path",
            gr.io_signature(0, 0, 0),  # Input signature
            gr.io_signature(0, 0, 0))  # Output signature

        options = copy.copy(
            options)  # make a copy so we can destructively modify

        self._which = options.which  # the USRP board attached
        self._verbose = options.verbose
        self._rx_freq = options.rx_freq  # receiver's center frequency
        self._rx_gain = options.rx_gain  # receiver's gain
        self._rx_subdev_spec = options.rx_subdev_spec  # daughterboard to use
        self._bitrate = options.bitrate  # desired bit rate
        self._decim = options.decim  # Decimating rate for the USRP (prelim)
        self._samples_per_symbol = options.samples_per_symbol  # desired samples/symbol
        self._fusb_block_size = options.fusb_block_size  # usb info for USRP
        self._fusb_nblocks = options.fusb_nblocks  # usb info for USRP

        self._rx_callback = rx_callback  # this callback is fired when there's a packet available
        self._demod_class = demod_class  # the demodulator_class we're using

        if self._rx_freq is None:
            sys.stderr.write(
                "-f FREQ or --freq FREQ or --rx-freq FREQ must be specified\n")
            raise SystemExit

    # Set up USRP source; also adjusts decim, samples_per_symbol, and bitrate
        self._setup_usrp_source()

        g = self.subdev.gain_range()
        if options.show_rx_gain_range:
            print "Rx Gain Range: minimum = %g, maximum = %g, step size = %g" \
                  % (g[0], g[1], g[2])

        self.set_gain(options.rx_gain)

        self.set_auto_tr(True)  # enable Auto Transmit/Receive switching

        # Set RF frequency
        ok = self.set_freq(self._rx_freq)
        if not ok:
            print "Failed to set Rx frequency to %s" % (
                eng_notation.num_to_str(self._rx_freq))
            raise ValueError, eng_notation.num_to_str(self._rx_freq)

    # copy the final answers back into options for use by demodulator
        options.samples_per_symbol = self._samples_per_symbol
        options.bitrate = self._bitrate
        options.decim = self._decim

        # Get demod_kwargs
        demod_kwargs = self._demod_class.extract_kwargs_from_options(options)

        # Design filter to get actual channel we want
        sw_decim = 1
        chan_coeffs = gr.firdes.low_pass(
            1.0,  # gain
            sw_decim * self._samples_per_symbol,  # sampling rate
            1.0,  # midpoint of trans. band
            0.5,  # width of trans. band
            gr.firdes.WIN_HANN)  # filter type

        # Decimating channel filter
        # complex in and out, float taps
        self.chan_filt = gr.fft_filter_ccc(sw_decim, chan_coeffs)
        #self.chan_filt = gr.fir_filter_ccf(sw_decim, chan_coeffs)

        # receiver
        self.packet_receiver = \
            blks2.demod_pkts(self._demod_class(**demod_kwargs),
                             access_code=None,
                             callback=self._rx_callback,
                             threshold=-1)

        # Carrier Sensing Blocks
        alpha = 0.001
        thresh = 30  # in dB, will have to adjust

        if options.log_rx_power == True:
            self.probe = gr.probe_avg_mag_sqrd_cf(thresh, alpha)
            self.power_sink = gr.file_sink(gr.sizeof_float, "rxpower.dat")
            self.connect(self.chan_filt, self.probe, self.power_sink)
        else:
            self.probe = gr.probe_avg_mag_sqrd_c(thresh, alpha)
            self.connect(self.chan_filt, self.probe)

    # Display some information about the setup
        if self._verbose:
            self._print_verbage()

        self.connect(self.u, self.chan_filt, self.packet_receiver)
예제 #30
0
파일: rx.py 프로젝트: randyp1248/darpa
    def __init__(self, options):
        gr.top_block.__init__(self)

        # Source block
        symbol_rate = 500000
        self.source = uhd_receiver(options.args, symbol_rate,
                                   2,
                                   options.rx_freq, 30,
                                   #options.spec, "RX2",
                                   options.spec, "TX/RX",
                                   1) #options.verbose)
        options.samples_per_symbol = self.source._sps


        RX_output_file = "RX_output_test_file"
	_RX_output_file = 'RX_output_test_file'
        #RX_output_file = "Ding_Dong2.wma"
	#_RX_output_file = 'Ding_Dong2.wma'


        RX_file_sink = gr.file_sink(gr.sizeof_char, RX_output_file)
	RX_output_filesize = os.stat(_RX_output_file).st_size
  
        #print RX_output_filesize



        self.filesink = gr.file_sink(1, "output_file")


	# Correlator block
        self.correlator = correlator_cc.correlator_cc()

	# Despreader block
	self.despreader = spreader.despreader_cb()
  
        # RS Decoder block
	self.decoder = rscoding_bb.decode_bb()

        # CRC RX Block
        self.crcrx = crc.crcrx()

	# Print block
	self.printer = print_bb.print_bb()

	# NULL sink block
        self.nullsink = gr.null_sink(1)
 
        # RRC filter
        #nfilts = 32 
        #ntaps = nfilts * 11 * int(options.samples_per_symbol)
        #self.rrc_taps = gr.firdes.root_raised_cosine(
            #1.0, # gain
            #1000000, # sampling rate based on 32 fliters in resampler
            #symbol_rate,    # symbol rate
            #1.0,    # excess bandwidth or roll-off factor
            #ntaps)
        #self.rrc_filter = gr.pfb_arb_resampler_ccf(options.samples_per_symbol, 
        #                                           self.rrc_taps)


        # Design filter to get actual channel we want
        sw_decim = 1
        chan_coeffs = gr.firdes.low_pass (1.0,                  # gain
                                          #sw_decim * self.samples_per_symbol(), # sampling rate
                                          #1000000, # sampling rate
                                          2,
                                          #self._chbw_factor,    # midpoint of trans. band
                                          1,    # midpoint of trans. band
                                          0.5,                  # width of trans. band
                                          gr.firdes.WIN_HANN)   # filter type
        self.channel_filter = gr.fft_filter_ccc(sw_decim, chan_coeffs)


	# Connect the blocks
        #self.connect(self.source, self.correlator)
        #self.connect(self.source, self.rrc_filter)
        #self.connect(self.rrc_filter, self.correlator)

        # connect block input to channel filter
	self.connect(self.source, self.channel_filter)
        self.connect(self.channel_filter, self.correlator)


        #self.connect(self.source, self.correlator)
        self.connect(self.correlator, self.despreader)
        self.connect(self.despreader, self.decoder)
        self.connect(self.decoder, self.crcrx)
        #self.connect(self.decoder, self.printer)
        #self.connect(self.printer, self.crcrx)
        #self.connect(self.despreader, self.printer)
        #self.connect(self.printer, self.nullsink)
        #self.connect(self.printer, self.filesink)
        #self.connect(self.crcrx, self.filesink)
        self.connect(self.crcrx, RX_file_sink)
예제 #31
0
    def __init__(self, demod_class, rx_callback, options, source_block):
        gr.hier_block2.__init__(self, "receive_path",
                                gr.io_signature(1, 1, gr.sizeof_gr_complex),
                                gr.io_signature(0, 0, 0))

        options = copy.copy(
            options)  # make a copy so we can destructively modify

        self._verbose = options.verbose
        self._bitrate = options.bitrate  # desired bit rate

        self._rx_callback = rx_callback  # this callback is fired when a packet arrives

        self._demod_class = demod_class  # the demodulator_class we're using

        self._chbw_factor = options.chbw_factor  # channel filter bandwidth factor

        # Get demod_kwargs
        demod_kwargs = self._demod_class.extract_kwargs_from_options(options)

        #Give hooks of usrp to blocks downstream
        self.source_block = source_block

        #########################################
        # Build Blocks
        #########################################

        # Build the demodulator
        self.demodulator = self._demod_class(**demod_kwargs)

        # Make sure the channel BW factor is between 1 and sps/2
        # or the filter won't work.
        if (self._chbw_factor < 1.0
                or self._chbw_factor > self.samples_per_symbol() / 2):
            sys.stderr.write(
                "Channel bandwidth factor ({0}) must be within the range [1.0, {1}].\n"
                .format(self._chbw_factor,
                        self.samples_per_symbol() / 2))
            sys.exit(1)

    # Design filter to get actual channel we want
        sw_decim = 1
        chan_coeffs = gr.firdes.low_pass(
            1.0,  # gain
            sw_decim * self.samples_per_symbol(),  # sampling rate
            self._chbw_factor,  # midpoint of trans. band
            0.5,  # width of trans. band
            gr.firdes.WIN_HANN)  # filter type
        self.channel_filter = gr.fft_filter_ccc(sw_decim, chan_coeffs)

        # receiver
        self.packet_receiver = \
            digital.demod_pkts(self.demodulator,
                               access_code=None,
                               callback=self._rx_callback,
                               threshold=-1)

        # Carrier Sensing Blocks
        alpha = 0.001
        thresh = 30  # in dB, will have to adjust
        self.probe = gr.probe_avg_mag_sqrd_c(thresh, alpha)

        # Display some information about the setup
        if self._verbose:
            self._print_verbage()

        # More Carrier Sensing with FFT
        #self.gr_vector_sink = gr.vector_sink_c(1024)
        #self.gr_stream_to_vector = gr.stream_to_vector(gr.sizeof_gr_complex*1, 1024)
        #self.gr_head = gr.head(gr.sizeof_gr_complex*1024, 1024)
        #self.fft = fft.fft_vcc(1024, True, (window.blackmanharris(1024)), True, 1)

        # Parameters
        usrp_rate = options.bitrate
        self.fft_size = 1024
        self.min_freq = 2.4e9 - 0.75e6
        self.max_freq = 2.4e9 + 0.75e6
        self.tune_delay = 0.001
        self.dwell_delay = 0.01

        s2v = gr.stream_to_vector(gr.sizeof_gr_complex, self.fft_size)

        mywindow = window.blackmanharris(self.fft_size)
        fft = gr.fft_vcc(self.fft_size, True, mywindow)
        power = 0
        for tap in mywindow:
            power += tap * tap

        c2mag = gr.complex_to_mag_squared(self.fft_size)

        # FIXME the log10 primitive is dog slow
        log = gr.nlog10_ff(
            10, self.fft_size, -20 * math.log10(self.fft_size) -
            10 * math.log10(power / self.fft_size))

        # Set the freq_step to 75% of the actual data throughput.
        # This allows us to discard the bins on both ends of the spectrum.
        #self.freq_step = 0.75 * usrp_rate
        #self.min_center_freq = self.min_freq + self.freq_step/2
        #nsteps = math.ceil((self.max_freq - self.min_freq) / self.freq_step)
        #self.max_center_freq = self.min_center_freq + (nsteps * self.freq_step)

        self.freq_step = 1.5e6
        self.min_center_freq = self.min_freq
        nsteps = 1
        self.max_center_freq = self.max_freq

        self.next_freq = self.min_center_freq

        tune_delay = max(0,
                         int(round(self.tune_delay * usrp_rate /
                                   self.fft_size)))  # in fft_frames
        dwell_delay = max(1,
                          int(
                              round(self.dwell_delay * usrp_rate /
                                    self.fft_size)))  # in fft_frames

        self.msgq = gr.msg_queue(16)
        self._tune_callback = tune(
            self)  # hang on to this to keep it from being GC'd
        stats = gr.bin_statistics_f(self.fft_size, self.msgq,
                                    self._tune_callback, tune_delay,
                                    dwell_delay)

        ######################################################
        # Connect Blocks Together
        ######################################################
        #channel-filter-->Probe_Avg_Mag_Sqrd
        #	       -->Packet_Receiver (Demod Done Here!!)
        #

        # connect FFT sampler to system
        #self.connect(self, self.gr_stream_to_vector, self.fft, self.gr_vector_sink)

        # connect block input to channel filter
        self.connect(self, self.channel_filter)

        # connect the channel input filter to the carrier power detector
        self.connect(self.channel_filter, self.probe)

        # connect channel filter to the packet receiver
        self.connect(self.channel_filter, self.packet_receiver)

        # FIXME leave out the log10 until we speed it up
        #self.connect(self.u, s2v, fft, c2mag, log, stats)
        self.connect(self.channel_filter, s2v, fft, c2mag, stats)
예제 #32
0
    def __init__(self, frame, panel, vbox, argv):
        stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv)

        self.frame = frame
        self.panel = panel
        
        parser = OptionParser(option_class=eng_option)
        parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=(0, 0),
                          help="select USRP Rx side A or B (default=A)")
        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("-Q", "--observing", type="eng_float", default=0.0,
                          help="set observing frequency to FREQ")
        parser.add_option("-a", "--avg", type="eng_float", default=1.0,
		help="set spectral averaging alpha")
        parser.add_option("-V", "--favg", type="eng_float", default=2.0,
                help="set folder averaging alpha")
        parser.add_option("-g", "--gain", type="eng_float", default=None,
                          help="set gain in dB (default is midpoint)")
        parser.add_option("-l", "--reflevel", type="eng_float", default=30.0,
                          help="Set pulse display reference level")
        parser.add_option("-L", "--lowest", type="eng_float", default=1.5,
                          help="Lowest valid frequency bin")
        parser.add_option("-e", "--longitude", type="eng_float", default=-76.02,                          help="Set Observer Longitude")
        parser.add_option("-c", "--latitude", type="eng_float", default=44.85,                          help="Set Observer Latitude")
        parser.add_option("-F", "--fft_size", type="eng_float", default=1024, help="Size of FFT")

        parser.add_option ("-t", "--threshold", type="eng_float", default=2.5, help="pulsar threshold")
        parser.add_option("-p", "--lowpass", type="eng_float", default=100, help="Pulse spectra cutoff freq")
        parser.add_option("-P", "--prefix", default="./", help="File prefix")
        parser.add_option("-u", "--pulsefreq", type="eng_float", default=0.748, help="Observation pulse rate")
        parser.add_option("-D", "--dm", type="eng_float", default=1.0e-5, help="Dispersion Measure")
        parser.add_option("-O", "--doppler", type="eng_float", default=1.0, help="Doppler ratio")
        parser.add_option("-B", "--divbase", type="eng_float", default=20, help="Y/Div menu base")
        parser.add_option("-I", "--division", type="eng_float", default=100, help="Y/Div")
        parser.add_option("-A", "--audio_source", default="plughw:0,0", help="Audio input device spec")
        parser.add_option("-N", "--num_pulses", default=1, type="eng_float", help="Number of display pulses")
        (options, args) = parser.parse_args()
        if len(args) != 0:
            parser.print_help()
            sys.exit(1)

        self.show_debug_info = True

        self.reflevel = options.reflevel
        self.divbase = options.divbase
        self.division = options.division
        self.audiodev = options.audio_source
        self.mult = int(options.num_pulses)

        # Low-pass cutoff for post-detector filter
        # Set to 100Hz usually, since lots of pulsars fit in this
        #   range
        self.lowpass = options.lowpass

        # What is lowest valid frequency bin in post-detector FFT?
        # There's some pollution very close to DC
        self.lowest_freq = options.lowest

        # What (dB) threshold to use in determining spectral candidates
        self.threshold = options.threshold

        # Filename prefix for recording file
        self.prefix = options.prefix

        # Dispersion Measure (DM)
        self.dm = options.dm

        # Doppler shift, as a ratio
        #  1.0 == no doppler shift
        #  1.005 == a little negative shift
        #  0.995 == a little positive shift
        self.doppler = options.doppler

        #
        # Input frequency and observing frequency--not necessarily the
        #   same thing, if we're looking at the IF of some downconverter
        #   that's ahead of the USRP and daughtercard.  This distinction
        #   is important in computing the correct de-dispersion filter.
        #
        self.frequency = options.freq
        if options.observing <= 0:
            self.observing_freq = options.freq
        else:
            self.observing_freq = options.observing
        
        # build the graph
        self.u = usrp.source_c(decim_rate=options.decim)
        self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))

        #
        # Recording file, in case we ever need to record baseband data
        #
        self.recording = gr.file_sink(gr.sizeof_char, "/dev/null")
        self.recording_state = False

        self.pulse_recording = gr.file_sink(gr.sizeof_short, "/dev/null")
        self.pulse_recording_state = False

        #
        # We come up with recording turned off, but the user may
        #  request recording later on
        self.recording.close()
        self.pulse_recording.close()

        #
        # Need these two for converting 12-bit baseband signals to 8-bit
        #
        self.tofloat = gr.complex_to_float()
        self.tochar = gr.float_to_char()

        # Need this for recording pulses (post-detector)
        self.toshort = gr.float_to_short()


        #
        # The spectral measurer sets this when it has a valid
        #   average spectral peak-to-peak distance
        # We can then use this to program the parameters for the epoch folder
        #
        # We set a sentimental value here
        self.pulse_freq = options.pulsefreq

        # Folder runs at this raw sample rate
        self.folder_input_rate = 20000

        # Each pulse in the epoch folder is sampled at 128 times the nominal
        #  pulse rate
        self.folding = 128

 
        #
        # Try to find candidate parameters for rational resampler
        #
        save_i = 0
        candidates = []
        for i in range(20,300):
            input_rate = self.folder_input_rate
            output_rate = int(self.pulse_freq * i)
            interp = gru.lcm(input_rate, output_rate) / input_rate
            decim = gru.lcm(input_rate, output_rate) / output_rate
            if (interp < 500 and decim < 250000):
                 candidates.append(i)

        # We didn't find anything, bail!
        if (len(candidates) < 1):
            print "Couldn't converge on resampler parameters"
            sys.exit(1)

        #
        # Now try to find candidate with the least sampling error
        #
        mindiff = 999.999
        for i in candidates:
            diff = self.pulse_freq * i
            diff = diff - int(diff)
            if (diff < mindiff):
                mindiff = diff
                save_i = i

        # Recompute rates
        input_rate = self.folder_input_rate
        output_rate = int(self.pulse_freq * save_i)

        # Compute new interp and decim, based on best candidate
        interp = gru.lcm(input_rate, output_rate) / input_rate
        decim = gru.lcm(input_rate, output_rate) / output_rate

        # Save optimized folding parameters, used later
        self.folding = save_i
        self.interp = int(interp)
        self.decim = int(decim)

        # So that we can view N pulses in the pulse viewer window
        FOLD_MULT=self.mult

        # determine the daughterboard subdevice we're using
        self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
        self.cardtype = self.u.daughterboard_id(0)

        # Compute raw input rate
        input_rate = self.u.adc_freq() / self.u.decim_rate()

        # BW==input_rate for complex data
        self.bw = input_rate

        #
        # Set baseband filter bandwidth if DBS_RX:
        #
        if self.cardtype == usrp_dbid.DBS_RX:
            lbw = input_rate / 2
            if lbw < 1.0e6:
                lbw = 1.0e6
            self.subdev.set_bw(lbw)

        #
        # We use this as a crude volume control for the audio output
        #
        #self.volume = gr.multiply_const_ff(10**(-1))
        

        #
        # Create location data for ephem package
        #
        self.locality = ephem.Observer()
        self.locality.long = str(options.longitude)
        self.locality.lat = str(options.latitude)

        #
        # What is the post-detector LPF cutoff for the FFT?
        #
        PULSAR_MAX_FREQ=int(options.lowpass)

        # First low-pass filters down to input_rate/FIRST_FACTOR
        #   and decimates appropriately
        FIRST_FACTOR=int(input_rate/(self.folder_input_rate/2))
        first_filter = gr.firdes.low_pass (1.0,
                                          input_rate,
                                          input_rate/FIRST_FACTOR,
                                          input_rate/(FIRST_FACTOR*20),         
                                          gr.firdes.WIN_HAMMING)

        # Second filter runs at the output rate of the first filter,
        #  And low-pass filters down to PULSAR_MAX_FREQ*10
        #
        second_input_rate =  int(input_rate/(FIRST_FACTOR/2))
        second_filter = gr.firdes.band_pass(1.0, second_input_rate,
                                          0.10,
                                          PULSAR_MAX_FREQ*10,
                                          PULSAR_MAX_FREQ*1.5,
                                          gr.firdes.WIN_HAMMING)

        # Third filter runs at PULSAR_MAX_FREQ*20
        #   and filters down to PULSAR_MAX_FREQ
        #
        third_input_rate = PULSAR_MAX_FREQ*20
        third_filter = gr.firdes_band_pass(1.0, third_input_rate,
                                           0.10, PULSAR_MAX_FREQ,
                                           PULSAR_MAX_FREQ/10.0,
                                           gr.firdes.WIN_HAMMING)


        #
        # Create the appropriate FFT scope
        #
        self.scope = ra_fftsink.ra_fft_sink_f (panel, 
           fft_size=int(options.fft_size), sample_rate=PULSAR_MAX_FREQ*2,
           title="Post-detector spectrum",  
           ofunc=self.pulsarfunc, xydfunc=self.xydfunc, fft_rate=200)

        #
        # Tell scope we're looking from DC to PULSAR_MAX_FREQ
        #
        self.scope.set_baseband_freq (0.0)


        #
        # Setup stripchart for showing pulse profiles
        #
        hz = "%5.3fHz " % self.pulse_freq
        per = "(%5.3f sec)" % (1.0/self.pulse_freq)
        sr = "%d sps" % (int(self.pulse_freq*self.folding))
        times = " %d Pulse Intervals" % self.mult
        self.chart = ra_stripchartsink.stripchart_sink_f (panel,
               sample_rate=1,
               stripsize=self.folding*FOLD_MULT, parallel=True, title="Pulse Profiles: "+hz+per+times, 
               xlabel="Seconds @ "+sr, ylabel="Level", autoscale=True,
               divbase=self.divbase, scaling=1.0/(self.folding*self.pulse_freq))
        self.chart.set_ref_level(self.reflevel)
        self.chart.set_y_per_div(self.division)

        # De-dispersion filter setup
        #
        # Do this here, just before creating the filter
        #  that will use the taps.
        #
        ntaps = self.compute_disp_ntaps(self.dm,self.bw,self.observing_freq)

        # Taps for the de-dispersion filter
        self.disp_taps = Numeric.zeros(ntaps,Numeric.Complex64)

        # Compute the de-dispersion filter now
        self.compute_dispfilter(self.dm,self.doppler,
            self.bw,self.observing_freq)

        #
        # Call constructors for receive chains
        #

        #
        # Now create the FFT filter using the computed taps
        self.dispfilt = gr.fft_filter_ccc(1, self.disp_taps)

        #
        # Audio sink
        #
        #print "input_rate ", second_input_rate, "audiodev ", self.audiodev
        #self.audio = audio.sink(second_input_rate, self.audiodev)

        #
        # The three post-detector filters
        # Done this way to allow an audio path (up to 10Khz)
        # ...and also because going from xMhz down to ~100Hz
        # In a single filter doesn't seem to work.
        #
        self.first = gr.fir_filter_fff (FIRST_FACTOR/2, first_filter)

        p = second_input_rate / (PULSAR_MAX_FREQ*20)
        self.second = gr.fir_filter_fff (int(p), second_filter)
        self.third = gr.fir_filter_fff (10, third_filter)

        # Detector
        self.detector = gr.complex_to_mag_squared()

        self.enable_comb_filter = False
        # Epoch folder comb filter
        if self.enable_comb_filter == True:
            bogtaps = Numeric.zeros(512, Numeric.Float64)
            self.folder_comb = gr.fft_filter_ccc(1,bogtaps)

        # Rational resampler
        self.folder_rr = blks2.rational_resampler_fff(self.interp, self.decim)

        # Epoch folder bandpass
        bogtaps = Numeric.zeros(1, Numeric.Float64)
        self.folder_bandpass = gr.fir_filter_fff (1, bogtaps)

        # Epoch folder F2C/C2F
        self.folder_f2c = gr.float_to_complex()
        self.folder_c2f = gr.complex_to_float()

        # Epoch folder S2P
        self.folder_s2p = gr.serial_to_parallel (gr.sizeof_float, 
             self.folding*FOLD_MULT)

        # Epoch folder IIR Filter (produces average pulse profiles)
        self.folder_iir = gr.single_pole_iir_filter_ff(1.0/options.favg,
             self.folding*FOLD_MULT)

        #
        # Set all the epoch-folder goop up
        #
        self.set_folding_params()

        # 
        # Start connecting configured modules in the receive chain
        #

        # Connect raw USRP to de-dispersion filter, detector
        self.connect(self.u, self.dispfilt, self.detector)

        # Connect detector output to FIR LPF
        #  in two stages, followed by the FFT scope
        self.connect(self.detector, self.first,
            self.second, self.third, self.scope)

        # Connect audio output
        #self.connect(self.first, self.volume)
        #self.connect(self.volume, (self.audio, 0))
        #self.connect(self.volume, (self.audio, 1))

        # Connect epoch folder
        if self.enable_comb_filter == True:
            self.connect (self.first, self.folder_bandpass, self.folder_rr,
                self.folder_f2c,
                self.folder_comb, self.folder_c2f,
                self.folder_s2p, self.folder_iir,
                self.chart)

        else:
            self.connect (self.first, self.folder_bandpass, self.folder_rr,
                self.folder_s2p, self.folder_iir, self.chart)

        # Connect baseband recording file (initially /dev/null)
        self.connect(self.u, self.tofloat, self.tochar, self.recording)

        # Connect pulse recording file (initially /dev/null)
        self.connect(self.first, self.toshort, self.pulse_recording)

        #
        # Build the GUI elements
        #
        self._build_gui(vbox)

        # Make GUI agree with command-line
        self.myform['average'].set_value(int(options.avg))
        self.myform['foldavg'].set_value(int(options.favg))


        # Make spectral averager agree with command line
        if options.avg != 1.0:
            self.scope.set_avg_alpha(float(1.0/options.avg))
            self.scope.set_average(True)


        # set initial values

        if options.gain is None:
            # if no gain was specified, use the mid-point in dB
            g = self.subdev.gain_range()
            options.gain = float(g[0]+g[1])/2

        if options.freq is None:
            # if no freq was specified, use the mid-point
            r = self.subdev.freq_range()
            options.freq = float(r[0]+r[1])/2

        self.set_gain(options.gain)
        #self.set_volume(-10.0)

        if not(self.set_freq(options.freq)):
            self._set_status_msg("Failed to set initial frequency")

        self.myform['decim'].set_value(self.u.decim_rate())
        self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate())
        self.myform['dbname'].set_value(self.subdev.name())
        self.myform['DM'].set_value(self.dm)
        self.myform['Doppler'].set_value(self.doppler)

        #
        # Start the timer that shows current LMST on the GUI
        #
        self.lmst_timer.Start(1000)
예제 #33
0
    def __init__(self, p, logging=False):
        """
    Hierarchical block for receiving OFDM symbols.

    The input is the complex modulated signal at baseband.
    Synchronized packets are sent back to the demodulator.

    @param params: Raw OFDM parameters
    @type  params: ofdm_params
    @param logging: turn file logging on or off
    @type  logging: bool
    """
        from numpy import fft

        gr.hier_block2.__init__(
            self,
            "ofdm_receiver",
            gr.io_signature(1, 1, gr.sizeof_gr_complex),  # Input signature
            gr.io_signature2(2, 2, gr.sizeof_gr_complex * p.occupied_tones,
                             gr.sizeof_char))  # Output signature

        # low-pass filter the input channel
        bw = (float(p.occupied_tones) / float(p.fft_length)) / 2.0
        tb = bw * 0.08
        lpf_coeffs = gr.firdes.low_pass(
            1.0,  # gain
            1.0,  # sampling rate
            bw + tb,  # midpoint of trans. band
            tb,  # width of trans. band
            gr.firdes.WIN_HAMMING)  # filter type
        lpf = gr.fft_filter_ccc(1, lpf_coeffs)
        #lpf = gr.add_const_cc(0.0)  ## no-op low-pass-filter
        self.connect(self, lpf)

        # to the synchronization algorithm
        #from gnuradio import blks2impl
        #from gnuradio.blks2impl.ofdm_sync_pn import ofdm_sync_pn
        sync = ofdm_sync(p.fft_length, p.cp_length, p.half_sync, logging)
        self.connect(lpf, sync)

        # correct for fine frequency offset computed in sync (up to +-pi/fft_length)
        # NOTE: frame_acquisition can correct coarse freq offset (i.e. kpi/fft_length)
        if p.half_sync:
            nco_sensitivity = 2.0 / p.fft_length
        else:
            nco_sensitivity = 1.0 / (p.fft_length + p.cp_length)
        #nco_sensitivity = 0

        nco = gr.frequency_modulator_fc(nco_sensitivity)
        sigmix = gr.multiply_cc()

        self.connect((sync, 0), (sigmix, 0))
        self.connect((sync, 1), nco, (sigmix, 1))

        # sample at symbol boundaries
        # NOTE: (sync,2) indicates the first sample of the symbol!
        sampler = raw.ofdm_sampler(p.fft_length,
                                   p.fft_length + p.cp_length,
                                   timeout=100)
        self.connect(sigmix, (sampler, 0))
        self.connect((sync, 2), (sampler, 1))  # timing signal to sample at

        # fft on the symbols
        win = [1 for i in range(p.fft_length)]
        # see gr_fft_vcc_fftw that it works differently if win = []
        fft = gr.fft_vcc(p.fft_length, True, win, True)
        self.connect((sampler, 0), fft)

        # use the preamble to correct the coarse frequency offset and initial equalizer
        frame_acq = raw.ofdm_frame_acquisition(p.fft_length, p.cp_length,
                                               p.preambles)

        self.frame_acq = frame_acq
        self.connect(fft, (frame_acq, 0))
        self.connect((sampler, 1), (frame_acq, 1))

        self.connect((frame_acq, 0),
                     (self, 0))  # finished with fine/coarse freq correction
        self.connect((frame_acq, 1), (self, 1))  # frame and symbol timing

        if logging:
            self.connect(lpf, gr.file_sink(gr.sizeof_gr_complex,
                                           "rx-filt.dat"))
            self.connect(
                fft,
                gr.file_sink(gr.sizeof_gr_complex * p.fft_length,
                             "rx-fft.dat"))
            self.connect((frame_acq, 0),
                         gr.file_sink(gr.sizeof_gr_complex * p.occupied_tones,
                                      "rx-acq.dat"))
            self.connect((frame_acq, 1), gr.file_sink(1, "rx-detect.datb"))
            self.connect(
                sampler,
                gr.file_sink(gr.sizeof_gr_complex * p.fft_length,
                             "rx-sampler.dat"))
            self.connect(sigmix,
                         gr.file_sink(gr.sizeof_gr_complex, "rx-sigmix.dat"))
            self.connect(nco, gr.file_sink(gr.sizeof_gr_complex, "rx-nco.dat"))
예제 #34
0
    def __init__(self, mpoints, taps=None):
        """
        Takes M complex streams in, produces single complex stream out
        that runs at M times the input sample rate

        @param mpoints: number of freq bins/interpolation factor/subbands
        @param taps:    filter taps for subband filter

        The channel spacing is equal to the input sample rate.
        The total bandwidth and output sample rate are equal the input
        sample rate * nchannels.

        Output stream to frequency mapping:
        
          channel zero is at zero frequency.

          if mpoints is odd:
            
            Channels with increasing positive frequencies come from
            channels 1 through (N-1)/2.

            Channel (N+1)/2 is the maximum negative frequency, and
            frequency increases through N-1 which is one channel lower
            than the zero frequency.

          if mpoints is even:

            Channels with increasing positive frequencies come from
            channels 1 through (N/2)-1.

            Channel (N/2) is evenly split between the max positive and
            negative bins.

            Channel (N/2)+1 is the maximum negative frequency, and
            frequency increases through N-1 which is one channel lower
            than the zero frequency.

            Channels near the frequency extremes end up getting cut
            off by subsequent filters and therefore have diminished
            utility.
        """
        item_size = gr.sizeof_gr_complex
        gr.hier_block2.__init__(self, "synthesis_filterbank",
                                gr.io_signature(mpoints, mpoints, item_size), # Input signature
                                gr.io_signature(1, 1, item_size))             # Output signature


        if taps is None:
            taps = _generate_synthesis_taps(mpoints)

        # pad taps to multiple of mpoints
        r = len(taps) % mpoints
        if r != 0:
            taps = taps + (mpoints - r) * (0,)

        # split in mpoints separate set of taps
        sub_taps = _split_taps(taps, mpoints)

        self.ss2v = gr.streams_to_vector(item_size, mpoints)
        self.ifft = gr.fft_vcc(mpoints, False, [])
        self.v2ss = gr.vector_to_streams(item_size, mpoints)
        # mpoints filters go in here...
        self.ss2s = gr.streams_to_stream(item_size, mpoints)

        for i in range(mpoints):
            self.connect((self, i), (self.ss2v, i))
            
        self.connect(self.ss2v, self.ifft, self.v2ss)

        # build mpoints fir filters...
        for i in range(mpoints):
            f = gr.fft_filter_ccc(1, sub_taps[i])
            self.connect((self.v2ss, i), f)
            self.connect(f, (self.ss2s, i))

	self.connect(self.ss2s, self)
예제 #35
0
	def __init__(self, ahw="default", freq=150.0e6, ppm=0.0, vol=1.0, ftune=0.0, xftune=0.0, srate=1.0e6, upclo=0.0, devinfo="rtl=0", agc=0, arate=48.0e3, upce=0, mthresh=-10.0, offs=50.e3, flist="", dfifo="multimode_fifo", mbw=2.0e3, deemph=75.0e-6, dmode="NFM1"):
		grc_wxgui.top_block_gui.__init__(self, title="Multimode Radio Receiver")
		_icon_path = "/usr/share/icons/hicolor/32x32/apps/gnuradio-grc.png"
		self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY))

		##################################################
		# Parameters
		##################################################
		self.ahw = ahw
		self.freq = freq
		self.ppm = ppm
		self.vol = vol
		self.ftune = ftune
		self.xftune = xftune
		self.srate = srate
		self.upclo = upclo
		self.devinfo = devinfo
		self.agc = agc
		self.arate = arate
		self.upce = upce
		self.mthresh = mthresh
		self.offs = offs
		self.flist = flist
		self.dfifo = dfifo
		self.mbw = mbw
		self.deemph = deemph
		self.dmode = dmode

		##################################################
		# Variables
		##################################################
		self.sc_list_str = sc_list_str = flist
		self.zoom = zoom = 1
		self.thresh = thresh = mthresh
		self.scan_rate = scan_rate = 15
		self.scan_power = scan_power = 0
		self.sc_low = sc_low = 150e6
		self.sc_listm = sc_listm = False
		self.sc_list = sc_list = eval("["+sc_list_str+"]")
		self.sc_incr = sc_incr = 12.5e3
		self.sc_high = sc_high = 300e6
		self.sc_ena = sc_ena = False
		self.samp_rate = samp_rate = int(mh.get_good_rate(devinfo,srate))
		self.rf_power = rf_power = 0
		self.ifreq = ifreq = freq
		self.zoomed_lp = zoomed_lp = (samp_rate/2.1)/zoom
		self.wbfm = wbfm = 200e3
		self.rf_d_power = rf_d_power = 0
		self.mode = mode = dmode
		self.logpower = logpower = math.log10(rf_power+1.0e-14)*10.0
		self.cur_freq = cur_freq = mh.scan_freq_out(sc_ena,sc_low,sc_high,freq,ifreq,scan_power+1.0e-14,thresh,sc_incr,scan_rate,sc_listm,sc_list)
		self.bw = bw = mbw
		self.audio_int_rate = audio_int_rate = 40e3
		self.zoom_taps = zoom_taps = firdes.low_pass(1.0,samp_rate,zoomed_lp,zoomed_lp/3,firdes.WIN_HAMMING,6.76)
		self.xfine = xfine = xftune
		self.volume = volume = vol
		self.variable_static_text_1 = variable_static_text_1 = cur_freq
		self.variable_static_text_0_0 = variable_static_text_0_0 = samp_rate
		self.variable_static_text_0 = variable_static_text_0 = float(int(math.log10(rf_d_power+1.0e-14)*100.0)/10.0)
		self.upc_offset = upc_offset = upclo
		self.upc = upc = upce
		self.ssbo = ssbo = -bw/2 if mode == "LSB" else 0.0
		self.sc_list_len = sc_list_len = len(sc_list)
		self.rfgain = rfgain = 25
		self.record_file = record_file = "recording.wav"
		self.record = record = False
		self.offset = offset = offs
		self.muted = muted = 0.0 if logpower >= thresh else 1
		self.main_taps = main_taps = firdes.low_pass(1.0,wbfm,mh.get_mode_deviation(mode,bw)*1.05,mh.get_mode_deviation(mode,bw)/2.0,firdes.WIN_HAMMING,6.76)
		self.k = k = wbfm/(2*math.pi*mh.get_mode_deviation(mode,bw))
		self.iagc = iagc = agc
		self.freq_update = freq_update = 0
		self.fine = fine = ftune
		self.digi_rate = digi_rate = 50e3
		self.aratio = aratio = int(wbfm/audio_int_rate)

		##################################################
		# Blocks
		##################################################
		self.rf_probe = gr.probe_avg_mag_sqrd_c(0, 0.015)
		self.Main = self.Main = wx.Notebook(self.GetWin(), style=wx.NB_TOP)
		self.Main.AddPage(grc_wxgui.Panel(self.Main), "Main Controls")
		self.Main.AddPage(grc_wxgui.Panel(self.Main), "Scan/Upconv Controls")
		self.Add(self.Main)
		self._zoom_chooser = forms.drop_down(
			parent=self.Main.GetPage(0).GetWin(),
			value=self.zoom,
			callback=self.set_zoom,
			label="Spectral Zoom Ratio",
			choices=[1, 2, 5, 10, 20, 50, 100],
			labels=[],
		)
		self.Main.GetPage(0).GridAdd(self._zoom_chooser, 1, 4, 1, 1)
		_xfine_sizer = wx.BoxSizer(wx.VERTICAL)
		self._xfine_text_box = forms.text_box(
			parent=self.Main.GetPage(0).GetWin(),
			sizer=_xfine_sizer,
			value=self.xfine,
			callback=self.set_xfine,
			label="Extra Fine Tuning",
			converter=forms.float_converter(),
			proportion=0,
		)
		self._xfine_slider = forms.slider(
			parent=self.Main.GetPage(0).GetWin(),
			sizer=_xfine_sizer,
			value=self.xfine,
			callback=self.set_xfine,
			minimum=-1.0e3,
			maximum=1.0e3,
			num_steps=200,
			style=wx.SL_HORIZONTAL,
			cast=float,
			proportion=1,
		)
		self.Main.GetPage(0).GridAdd(_xfine_sizer, 0, 3, 1, 1)
		_volume_sizer = wx.BoxSizer(wx.VERTICAL)
		self._volume_text_box = forms.text_box(
			parent=self.Main.GetPage(0).GetWin(),
			sizer=_volume_sizer,
			value=self.volume,
			callback=self.set_volume,
			label="Volume",
			converter=forms.float_converter(),
			proportion=0,
		)
		self._volume_slider = forms.slider(
			parent=self.Main.GetPage(0).GetWin(),
			sizer=_volume_sizer,
			value=self.volume,
			callback=self.set_volume,
			minimum=1.0,
			maximum=10.0,
			num_steps=100,
			style=wx.SL_HORIZONTAL,
			cast=float,
			proportion=1,
		)
		self.Main.GetPage(0).GridAdd(_volume_sizer, 0, 0, 1, 1)
		self._upc_offset_text_box = forms.text_box(
			parent=self.Main.GetPage(1).GetWin(),
			value=self.upc_offset,
			callback=self.set_upc_offset,
			label="Upconv. LO Freq",
			converter=forms.float_converter(),
		)
		self.Main.GetPage(1).GridAdd(self._upc_offset_text_box, 3, 2, 1, 2)
		self._upc_check_box = forms.check_box(
			parent=self.Main.GetPage(1).GetWin(),
			value=self.upc,
			callback=self.set_upc,
			label="Ext. Upconv.",
			true=1,
			false=0,
		)
		self.Main.GetPage(1).GridAdd(self._upc_check_box, 3, 0, 1, 1)
		_rfgain_sizer = wx.BoxSizer(wx.VERTICAL)
		self._rfgain_text_box = forms.text_box(
			parent=self.Main.GetPage(0).GetWin(),
			sizer=_rfgain_sizer,
			value=self.rfgain,
			callback=self.set_rfgain,
			label="RF Gain",
			converter=forms.float_converter(),
			proportion=0,
		)
		self._rfgain_slider = forms.slider(
			parent=self.Main.GetPage(0).GetWin(),
			sizer=_rfgain_sizer,
			value=self.rfgain,
			callback=self.set_rfgain,
			minimum=0,
			maximum=50,
			num_steps=200,
			style=wx.SL_HORIZONTAL,
			cast=float,
			proportion=1,
		)
		self.Main.GetPage(0).GridAdd(_rfgain_sizer, 2, 1, 1, 1)
		self._record_file_text_box = forms.text_box(
			parent=self.Main.GetPage(0).GetWin(),
			value=self.record_file,
			callback=self.set_record_file,
			label="Recording Filename",
			converter=forms.str_converter(),
		)
		self.Main.GetPage(0).GridAdd(self._record_file_text_box, 2, 3, 1, 3)
		self._record_check_box = forms.check_box(
			parent=self.Main.GetPage(0).GetWin(),
			value=self.record,
			callback=self.set_record,
			label="Record",
			true=True,
			false=False,
		)
		self.Main.GetPage(0).GridAdd(self._record_check_box, 2, 2, 1, 1)
		_offset_sizer = wx.BoxSizer(wx.VERTICAL)
		self._offset_text_box = forms.text_box(
			parent=self.Main.GetPage(0).GetWin(),
			sizer=_offset_sizer,
			value=self.offset,
			callback=self.set_offset,
			label="LO Offset",
			converter=forms.float_converter(),
			proportion=0,
		)
		self._offset_slider = forms.slider(
			parent=self.Main.GetPage(0).GetWin(),
			sizer=_offset_sizer,
			value=self.offset,
			callback=self.set_offset,
			minimum=25e3,
			maximum=500e3,
			num_steps=200,
			style=wx.SL_HORIZONTAL,
			cast=float,
			proportion=1,
		)
		self.Main.GetPage(0).GridAdd(_offset_sizer, 1, 3, 1, 1)
		self._mode_chooser = forms.drop_down(
			parent=self.Main.GetPage(0).GetWin(),
			value=self.mode,
			callback=self.set_mode,
			label="Mode",
			choices=mh.get_modes_values(),
			labels=mh.get_modes_names(),
		)
		self.Main.GetPage(0).GridAdd(self._mode_chooser, 0, 4, 1, 1)
		self._iagc_check_box = forms.check_box(
			parent=self.Main.GetPage(0).GetWin(),
			value=self.iagc,
			callback=self.set_iagc,
			label="AGC",
			true=1,
			false=0,
		)
		self.Main.GetPage(0).GridAdd(self._iagc_check_box, 2, 0, 1, 1)
		def _freq_update_probe():
			while True:
				val = self.rf_probe.level()
				try: self.set_freq_update(val)
				except AttributeError, e: pass
				time.sleep(1.0/(1.0/(2.5)))
		_freq_update_thread = threading.Thread(target=_freq_update_probe)
		_freq_update_thread.daemon = True
		_freq_update_thread.start()
		_fine_sizer = wx.BoxSizer(wx.VERTICAL)
		self._fine_text_box = forms.text_box(
			parent=self.Main.GetPage(0).GetWin(),
			sizer=_fine_sizer,
			value=self.fine,
			callback=self.set_fine,
			label="Fine Tuning",
			converter=forms.float_converter(),
			proportion=0,
		)
		self._fine_slider = forms.slider(
			parent=self.Main.GetPage(0).GetWin(),
			sizer=_fine_sizer,
			value=self.fine,
			callback=self.set_fine,
			minimum=-35e3,
			maximum=35e3,
			num_steps=100,
			style=wx.SL_HORIZONTAL,
			cast=float,
			proportion=1,
		)
		self.Main.GetPage(0).GridAdd(_fine_sizer, 0, 2, 1, 1)
		self.display_probe = gr.probe_avg_mag_sqrd_c(0, 0.002)
		_bw_sizer = wx.BoxSizer(wx.VERTICAL)
		self._bw_text_box = forms.text_box(
			parent=self.Main.GetPage(0).GetWin(),
			sizer=_bw_sizer,
			value=self.bw,
			callback=self.set_bw,
			label="AM/SSB Bandwidth",
			converter=forms.float_converter(),
			proportion=0,
		)
		self._bw_slider = forms.slider(
			parent=self.Main.GetPage(0).GetWin(),
			sizer=_bw_sizer,
			value=self.bw,
			callback=self.set_bw,
			minimum=1.0e3,
			maximum=audio_int_rate/2,
			num_steps=100,
			style=wx.SL_HORIZONTAL,
			cast=float,
			proportion=1,
		)
		self.Main.GetPage(0).GridAdd(_bw_sizer, 1, 2, 1, 1)
		self.wxgui_waterfallsink2_0 = waterfallsink2.waterfall_sink_c(
			self.Main.GetPage(0).GetWin(),
			baseband_freq=mh.get_last_returned(freq_update),
			dynamic_range=40,
			ref_level=0,
			ref_scale=2.0,
			sample_rate=samp_rate/zoom,
			fft_size=1024,
			fft_rate=4,
			average=True,
			avg_alpha=None,
			title="Spectrogram",
			win=window.hamming,
		)
		self.Main.GetPage(0).Add(self.wxgui_waterfallsink2_0.win)
		def wxgui_waterfallsink2_0_callback(x, y):
			self.set_freq(x)
		
		self.wxgui_waterfallsink2_0.set_callback(wxgui_waterfallsink2_0_callback)
		self.wxgui_fftsink2_0 = fftsink2.fft_sink_c(
			self.Main.GetPage(0).GetWin(),
			baseband_freq=mh.get_last_returned(freq_update),
			y_per_div=10,
			y_divs=10,
			ref_level=0,
			ref_scale=2.0,
			sample_rate=samp_rate/zoom,
			fft_size=1024,
			fft_rate=4,
			average=True,
			avg_alpha=0.1,
			title="Panorama",
			peak_hold=False,
			win=window.hamming,
		)
		self.Main.GetPage(0).Add(self.wxgui_fftsink2_0.win)
		def wxgui_fftsink2_0_callback(x, y):
			self.set_freq(x)
		
		self.wxgui_fftsink2_0.set_callback(wxgui_fftsink2_0_callback)
		self._variable_static_text_1_static_text = forms.static_text(
			parent=self.Main.GetPage(1).GetWin(),
			value=self.variable_static_text_1,
			callback=self.set_variable_static_text_1,
			label="Current Scan Freq",
			converter=forms.float_converter(),
		)
		self.Main.GetPage(1).GridAdd(self._variable_static_text_1_static_text, 0, 5, 1, 2)
		self._variable_static_text_0_0_static_text = forms.static_text(
			parent=self.Main.GetPage(0).GetWin(),
			value=self.variable_static_text_0_0,
			callback=self.set_variable_static_text_0_0,
			label="Actual srate",
			converter=forms.float_converter(),
		)
		self.Main.GetPage(0).GridAdd(self._variable_static_text_0_0_static_text, 1, 5, 1, 1)
		self._variable_static_text_0_static_text = forms.static_text(
			parent=self.Main.GetPage(0).GetWin(),
			value=self.variable_static_text_0,
			callback=self.set_variable_static_text_0,
			label="RF Level",
			converter=forms.float_converter(),
		)
		self.Main.GetPage(0).GridAdd(self._variable_static_text_0_static_text, 1, 0, 1, 1)
		_thresh_sizer = wx.BoxSizer(wx.VERTICAL)
		self._thresh_text_box = forms.text_box(
			parent=self.Main.GetPage(0).GetWin(),
			sizer=_thresh_sizer,
			value=self.thresh,
			callback=self.set_thresh,
			label="Mute Threshold",
			converter=forms.float_converter(),
			proportion=0,
		)
		self._thresh_slider = forms.slider(
			parent=self.Main.GetPage(0).GetWin(),
			sizer=_thresh_sizer,
			value=self.thresh,
			callback=self.set_thresh,
			minimum=-50,
			maximum=10,
			num_steps=100,
			style=wx.SL_HORIZONTAL,
			cast=float,
			proportion=1,
		)
		self.Main.GetPage(0).GridAdd(_thresh_sizer, 1, 1, 1, 1)
		def _scan_power_probe():
			while True:
				val = self.rf_probe.level()
				try: self.set_scan_power(val)
				except AttributeError, e: pass
				time.sleep(1.0/(scan_rate))
		_scan_power_thread = threading.Thread(target=_scan_power_probe)
		_scan_power_thread.daemon = True
		_scan_power_thread.start()
		self._sc_low_text_box = forms.text_box(
			parent=self.Main.GetPage(1).GetWin(),
			value=self.sc_low,
			callback=self.set_sc_low,
			label="Scan Low",
			converter=forms.float_converter(),
		)
		self.Main.GetPage(1).GridAdd(self._sc_low_text_box, 0, 1, 1, 1)
		self._sc_listm_check_box = forms.check_box(
			parent=self.Main.GetPage(1).GetWin(),
			value=self.sc_listm,
			callback=self.set_sc_listm,
			label="Scan List Mode",
			true=True,
			false=False,
		)
		self.Main.GetPage(1).GridAdd(self._sc_listm_check_box, 2, 0, 1, 1)
		self._sc_list_str_text_box = forms.text_box(
			parent=self.Main.GetPage(1).GetWin(),
			value=self.sc_list_str,
			callback=self.set_sc_list_str,
			label="Scan List",
			converter=forms.str_converter(),
		)
		self.Main.GetPage(1).GridAdd(self._sc_list_str_text_box, 2, 1, 1, 5)
		self._sc_incr_chooser = forms.drop_down(
			parent=self.Main.GetPage(1).GetWin(),
			value=self.sc_incr,
			callback=self.set_sc_incr,
			label="Scan Increment (Hz)",
			choices=[5.0e3,6.25e3,10.0e3,12.5e3,15e3,25e3],
			labels=[],
		)
		self.Main.GetPage(1).GridAdd(self._sc_incr_chooser, 0, 0, 1, 1)
		self._sc_high_text_box = forms.text_box(
			parent=self.Main.GetPage(1).GetWin(),
			value=self.sc_high,
			callback=self.set_sc_high,
			label="Scan High",
			converter=forms.float_converter(),
		)
		self.Main.GetPage(1).GridAdd(self._sc_high_text_box, 0, 2, 1, 1)
		self._sc_ena_check_box = forms.check_box(
			parent=self.Main.GetPage(1).GetWin(),
			value=self.sc_ena,
			callback=self.set_sc_ena,
			label="Scan Enable",
			true=True,
			false=False,
		)
		self.Main.GetPage(1).GridAdd(self._sc_ena_check_box, 0, 3, 1, 1)
		def _rf_power_probe():
			while True:
				val = self.rf_probe.level()
				try: self.set_rf_power(val)
				except AttributeError, e: pass
				time.sleep(1.0/(10))
		_rf_power_thread = threading.Thread(target=_rf_power_probe)
		_rf_power_thread.daemon = True
		_rf_power_thread.start()
		def _rf_d_power_probe():
			while True:
				val = self.display_probe.level()
				try: self.set_rf_d_power(val)
				except AttributeError, e: pass
				time.sleep(1.0/(5))
		_rf_d_power_thread = threading.Thread(target=_rf_d_power_probe)
		_rf_d_power_thread.daemon = True
		_rf_d_power_thread.start()
		self.osmosdr_source_c_0 = osmosdr.source_c( args="nchan=" + str(1) + " " + devinfo )
		self.osmosdr_source_c_0.set_sample_rate(samp_rate)
		self.osmosdr_source_c_0.set_center_freq(cur_freq+offset+(upc_offset*float(upc)), 0)
		self.osmosdr_source_c_0.set_freq_corr(ppm, 0)
		self.osmosdr_source_c_0.set_gain_mode(iagc, 0)
		self.osmosdr_source_c_0.set_gain(25 if iagc == 1 else rfgain, 0)
		self.osmosdr_source_c_0.set_if_gain(20, 0)
			
		self._ifreq_text_box = forms.text_box(
			parent=self.Main.GetPage(0).GetWin(),
			value=self.ifreq,
			callback=self.set_ifreq,
			label="Frequency",
			converter=forms.float_converter(),
		)
		self.Main.GetPage(0).GridAdd(self._ifreq_text_box, 0, 1, 1, 1)
		self.gr_wavfile_sink_0 = gr.wavfile_sink("/dev/null" if record == False else record_file, 1, int(audio_int_rate), 8)
		self.gr_quadrature_demod_cf_0 = gr.quadrature_demod_cf(k)
		self.gr_multiply_const_vxx_2 = gr.multiply_const_vff((1.0 if mh.get_mode_type(mode) == "FM" else 0.0, ))
		self.gr_multiply_const_vxx_1 = gr.multiply_const_vff((0.0 if muted else volume/4.5, ))
		self.gr_multiply_const_vxx_0_0_0 = gr.multiply_const_vff((0.85 if mh.get_mode_type(mode) == "AM" else 0.0, ))
		self.gr_multiply_const_vxx_0_0 = gr.multiply_const_vff((0.85 if mh.get_mode_type(mode) == "SSB" else 0.0, ))
		self.gr_multiply_const_vxx_0 = gr.multiply_const_vcc(((1.0/math.sqrt(mh.get_mode_deviation(mode,bw))*250), ))
		self.gr_keep_one_in_n_1 = gr.keep_one_in_n(gr.sizeof_gr_complex*1, aratio)
		self.gr_keep_one_in_n_0_0 = gr.keep_one_in_n(gr.sizeof_gr_complex*1, zoom)
		self.gr_keep_one_in_n_0 = gr.keep_one_in_n(gr.sizeof_gr_complex*1, int(wbfm/digi_rate))
		self.gr_freq_xlating_fir_filter_xxx_0_1 = gr.freq_xlating_fir_filter_ccc(1, (1.0, ), (offset+fine+xfine)/(samp_rate/1.0e6), samp_rate)
		self.gr_fractional_interpolator_xx_0 = gr.fractional_interpolator_ff(0, audio_int_rate/arate)
		self.gr_file_sink_0 = gr.file_sink(gr.sizeof_gr_complex*1, "/dev/null" if mh.get_mode_type(mode) != "DIG" else dfifo)
		self.gr_file_sink_0.set_unbuffered(True)
		self.gr_fft_filter_xxx_3 = gr.fft_filter_ccc(1, (zoom_taps), 1)
		self.gr_fft_filter_xxx_2_0 = gr.fft_filter_fff(5, (firdes.low_pass(1.0,wbfm,14.5e3,8.5e3,firdes.WIN_HAMMING,6.76)), 1)
		self.gr_fft_filter_xxx_2 = gr.fft_filter_ccc(1, (main_taps), 1)
		self.gr_fft_filter_xxx_0 = gr.fft_filter_ccc(int(samp_rate/wbfm), (firdes.low_pass(1.0,samp_rate,98.5e3,66e3,firdes.WIN_HAMMING,6.76)), 1)
		self.gr_feedforward_agc_cc_0 = gr.feedforward_agc_cc(1024, 0.75)
		self.gr_complex_to_real_0 = gr.complex_to_real(1)
		self.gr_complex_to_mag_squared_0 = gr.complex_to_mag_squared(1)
		self.gr_add_xx_0 = gr.add_vff(1)
		self.blks2_fm_deemph_0 = blks2.fm_deemph(fs=audio_int_rate, tau=deemph)
		self.audio_sink_0 = audio.sink(int(arate), ahw, True)

		##################################################
		# Connections
		##################################################
		self.connect((self.gr_multiply_const_vxx_0_0, 0), (self.gr_add_xx_0, 1))
		self.connect((self.gr_fractional_interpolator_xx_0, 0), (self.gr_multiply_const_vxx_1, 0))
		self.connect((self.gr_multiply_const_vxx_1, 0), (self.audio_sink_0, 0))
		self.connect((self.gr_multiply_const_vxx_1, 0), (self.audio_sink_0, 1))
		self.connect((self.gr_feedforward_agc_cc_0, 0), (self.gr_complex_to_mag_squared_0, 0))
		self.connect((self.osmosdr_source_c_0, 0), (self.gr_freq_xlating_fir_filter_xxx_0_1, 0))
		self.connect((self.gr_multiply_const_vxx_0_0_0, 0), (self.gr_add_xx_0, 2))
		self.connect((self.gr_feedforward_agc_cc_0, 0), (self.gr_complex_to_real_0, 0))
		self.connect((self.gr_complex_to_real_0, 0), (self.gr_multiply_const_vxx_0_0, 0))
		self.connect((self.gr_multiply_const_vxx_2, 0), (self.gr_add_xx_0, 0))
		self.connect((self.gr_complex_to_mag_squared_0, 0), (self.gr_multiply_const_vxx_0_0_0, 0))
		self.connect((self.gr_multiply_const_vxx_0, 0), (self.display_probe, 0))
		self.connect((self.gr_multiply_const_vxx_0, 0), (self.rf_probe, 0))
		self.connect((self.gr_add_xx_0, 0), (self.gr_fractional_interpolator_xx_0, 0))
		self.connect((self.gr_add_xx_0, 0), (self.gr_wavfile_sink_0, 0))
		self.connect((self.gr_freq_xlating_fir_filter_xxx_0_1, 0), (self.gr_fft_filter_xxx_0, 0))
		self.connect((self.gr_keep_one_in_n_0, 0), (self.gr_file_sink_0, 0))
		self.connect((self.gr_freq_xlating_fir_filter_xxx_0_1, 0), (self.gr_fft_filter_xxx_3, 0))
		self.connect((self.gr_fft_filter_xxx_3, 0), (self.gr_keep_one_in_n_0_0, 0))
		self.connect((self.gr_keep_one_in_n_0_0, 0), (self.wxgui_fftsink2_0, 0))
		self.connect((self.gr_keep_one_in_n_0_0, 0), (self.wxgui_waterfallsink2_0, 0))
		self.connect((self.blks2_fm_deemph_0, 0), (self.gr_multiply_const_vxx_2, 0))
		self.connect((self.gr_quadrature_demod_cf_0, 0), (self.gr_fft_filter_xxx_2_0, 0))
		self.connect((self.gr_fft_filter_xxx_2, 0), (self.gr_keep_one_in_n_0, 0))
		self.connect((self.gr_fft_filter_xxx_2, 0), (self.gr_multiply_const_vxx_0, 0))
		self.connect((self.gr_fft_filter_xxx_0, 0), (self.gr_fft_filter_xxx_2, 0))
		self.connect((self.gr_keep_one_in_n_1, 0), (self.gr_feedforward_agc_cc_0, 0))
		self.connect((self.gr_fft_filter_xxx_2, 0), (self.gr_keep_one_in_n_1, 0))
		self.connect((self.gr_fft_filter_xxx_2, 0), (self.gr_quadrature_demod_cf_0, 0))
		self.connect((self.gr_fft_filter_xxx_2_0, 0), (self.blks2_fm_deemph_0, 0))
예제 #36
0
파일: raw_ofdm_rx.py 프로젝트: UpYou/ofdm
  def __init__(self, p, logging=False):
    """
    Hierarchical block for receiving OFDM symbols.

    The input is the complex modulated signal at baseband.
    Synchronized packets are sent back to the demodulator.

    @param params: Raw OFDM parameters
    @type  params: ofdm_params
    @param logging: turn file logging on or off
    @type  logging: bool
    """
    from numpy import fft

    gr.hier_block2.__init__(self, "ofdm_receiver",
      gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
      gr.io_signature2(2, 2, gr.sizeof_gr_complex*p.occupied_tones, gr.sizeof_char)) # Output signature

    # low-pass filter the input channel
    bw = (float(p.occupied_tones) / float(p.fft_length)) / 2.0
    tb = bw*0.08
    lpf_coeffs = gr.firdes.low_pass (1.0,                     # gain
                                     1.0,                     # sampling rate
                                     bw+tb,                   # midpoint of trans. band
                                     tb,                      # width of trans. band
                                     gr.firdes.WIN_HAMMING)   # filter type
    lpf = gr.fft_filter_ccc(1, lpf_coeffs)
    #lpf = gr.add_const_cc(0.0)  ## no-op low-pass-filter
    self.connect(self, lpf)

    # to the synchronization algorithm
    #from gnuradio import blks2impl
    #from gnuradio.blks2impl.ofdm_sync_pn import ofdm_sync_pn
    sync = ofdm_sync(p.fft_length, p.cp_length, p.half_sync, logging)
    self.connect(lpf, sync)

    # correct for fine frequency offset computed in sync (up to +-pi/fft_length)
    # NOTE: frame_acquisition can correct coarse freq offset (i.e. kpi/fft_length)
    if p.half_sync:
      nco_sensitivity = 2.0/p.fft_length
    else:
      nco_sensitivity = 1.0/(p.fft_length + p.cp_length)
    #nco_sensitivity = 0

    nco = gr.frequency_modulator_fc(nco_sensitivity)
    sigmix = gr.multiply_cc()

    self.connect((sync,0), (sigmix,0))
    self.connect((sync,1), nco, (sigmix,1))

    # sample at symbol boundaries
    # NOTE: (sync,2) indicates the first sample of the symbol!
    sampler = raw.ofdm_sampler(p.fft_length, p.fft_length+p.cp_length, timeout=100)
    self.connect(sigmix, (sampler,0))
    self.connect((sync,2), (sampler,1))  # timing signal to sample at

    # fft on the symbols
    win = [1 for i in range(p.fft_length)]
    # see gr_fft_vcc_fftw that it works differently if win = []
    fft = gr.fft_vcc(p.fft_length, True, win, True)
    self.connect((sampler,0), fft)

    # use the preamble to correct the coarse frequency offset and initial equalizer
    frame_acq = raw.ofdm_frame_acquisition(p.fft_length, p.cp_length, p.preambles)

    self.frame_acq = frame_acq
    self.connect(fft, (frame_acq,0))
    self.connect((sampler,1), (frame_acq,1))

    self.connect((frame_acq,0), (self,0))  # finished with fine/coarse freq correction
    self.connect((frame_acq,1), (self,1))  # frame and symbol timing

    if logging:
      self.connect(lpf,
                   gr.file_sink(gr.sizeof_gr_complex, "rx-filt.dat"))
      self.connect(fft,
                   gr.file_sink(gr.sizeof_gr_complex*p.fft_length, "rx-fft.dat"))
      self.connect((frame_acq,0),
                   gr.file_sink(gr.sizeof_gr_complex*p.occupied_tones, "rx-acq.dat"))
      self.connect((frame_acq,1),
                   gr.file_sink(1, "rx-detect.datb"))
      self.connect(sampler,
                   gr.file_sink(gr.sizeof_gr_complex*p.fft_length, "rx-sampler.dat"))
      self.connect(sigmix,
                   gr.file_sink(gr.sizeof_gr_complex, "rx-sigmix.dat"))
      self.connect(nco,
                   gr.file_sink(gr.sizeof_gr_complex, "rx-nco.dat"))
예제 #37
0
파일: ofdm.py 프로젝트: ariendj/gr-dab
	def __init__(self, dab_params, rx_params, verbose=False, debug=False):
		"""
		Hierarchical block for OFDM demodulation

		@param dab_params DAB parameter object (dab.parameters.dab_parameters)
		@param rx_params RX parameter object (dab.parameters.receiver_parameters)
		@param debug enables debug output to files
		@param verbose whether to produce verbose messages
		"""

		self.dp = dp = dab_params
		self.rp = rp = rx_params
		self.verbose = verbose

		if self.rp.softbits:
			gr.hier_block2.__init__(self,"ofdm_demod",
						gr.io_signature (1, 1, gr.sizeof_gr_complex), # input signature
						gr.io_signature2(2, 2, gr.sizeof_float*self.dp.num_carriers*2, gr.sizeof_char)) # output signature
		else:
			gr.hier_block2.__init__(self,"ofdm_demod",
						gr.io_signature (1, 1, gr.sizeof_gr_complex), # input signature
						gr.io_signature2(2, 2, gr.sizeof_char*self.dp.num_carriers/4, gr.sizeof_char)) # output signature

		

		# workaround for a problem that prevents connecting more than one block directly (see trac ticket #161)
		self.input = gr.kludge_copy(gr.sizeof_gr_complex)
		self.connect(self, self.input)
		
		# input filtering
		if self.rp.input_fft_filter: 
			if verbose: print "--> RX filter enabled"
			lowpass_taps = gr.firdes_low_pass(1.0,                     # gain
							  dp.sample_rate,          # sampling rate
							  rp.filt_bw,              # cutoff frequency
							  rp.filt_tb,              # width of transition band
							  gr.firdes.WIN_HAMMING)   # Hamming window
			self.fft_filter = gr.fft_filter_ccc(1, lowpass_taps)
		

		# correct sample rate offset, if enabled
		if self.rp.autocorrect_sample_rate:
			if verbose: print "--> dynamic sample rate correction enabled"
			self.rate_detect_ns = detect_null.detect_null(dp.ns_length, False)
			self.rate_estimator = dab_swig.estimate_sample_rate_bf(dp.sample_rate, dp.frame_length)
			self.rate_prober = gr.probe_signal_f()
			self.connect(self.input, self.rate_detect_ns, self.rate_estimator, self.rate_prober)
			# self.resample = gr.fractional_interpolator_cc(0, 1)
			self.resample = dab_swig.fractional_interpolator_triggered_update_cc(0,1)
			self.connect(self.rate_detect_ns, (self.resample,1))
			self.updater = Timer(0.1,self.update_correction)
			# self.updater = threading.Thread(target=self.update_correction)
			self.run_interpolater_update_thread = True
			self.updater.setDaemon(True)
			self.updater.start()
		else:
			self.run_interpolater_update_thread = False
			if self.rp.sample_rate_correction_factor != 1:
				if verbose: print "--> static sample rate correction enabled"
				self.resample = gr.fractional_interpolator_cc(0, self.rp.sample_rate_correction_factor)

		# timing and fine frequency synchronisation
		self.sync = ofdm_sync_dab2.ofdm_sync_dab(self.dp, self.rp, debug)

		# ofdm symbol sampler
		self.sampler = dab_swig.ofdm_sampler(dp.fft_length, dp.cp_length, dp.symbols_per_frame, rp.cp_gap)
		
		# fft for symbol vectors
		self.fft = gr.fft_vcc(dp.fft_length, True, [], True)

		# coarse frequency synchronisation
		self.cfs = dab_swig.ofdm_coarse_frequency_correct(dp.fft_length, dp.num_carriers, dp.cp_length)

		# diff phasor
		self.phase_diff = dab_swig.diff_phasor_vcc(dp.num_carriers)

		# remove pilot symbol
		self.remove_pilot = dab_swig.ofdm_remove_first_symbol_vcc(dp.num_carriers)

		# magnitude equalisation
		if self.rp.equalize_magnitude:
			if verbose: print "--> magnitude equalization enabled"
			self.equalizer = dab_swig.magnitude_equalizer_vcc(dp.num_carriers, rp.symbols_for_magnitude_equalization)

		# frequency deinterleaving
		self.deinterleave = dab_swig.frequency_interleaver_vcc(dp.frequency_deinterleaving_sequence_array)
		
		# symbol demapping
		self.demapper = dab_swig.qpsk_demapper_vcb(dp.num_carriers)

		#
		# connect everything
		#

		if self.rp.autocorrect_sample_rate or self.rp.sample_rate_correction_factor != 1:
			self.connect(self.input, self.resample)
			self.input2 = self.resample
		else:
			self.input2 = self.input
		if self.rp.input_fft_filter:
			self.connect(self.input2, self.fft_filter, self.sync)
		else:
			self.connect(self.input2, self.sync)

		# data stream
		self.connect((self.sync, 0), (self.sampler, 0), self.fft, (self.cfs, 0), self.phase_diff, (self.remove_pilot,0))
		if self.rp.equalize_magnitude:
			self.connect((self.remove_pilot,0), (self.equalizer,0), self.deinterleave)
		else:
			self.connect((self.remove_pilot,0), self.deinterleave)
		if self.rp.softbits:
			if verbose: print "--> using soft bits"
			self.softbit_interleaver = dab_swig.complex_to_interleaved_float_vcf(self.dp.num_carriers)
			self.connect(self.deinterleave, self.softbit_interleaver, (self,0))
		else:
			self.connect(self.deinterleave, self.demapper, (self,0))

		# control stream
		self.connect((self.sync, 1), (self.sampler, 1), (self.cfs, 1), (self.remove_pilot,1))
		if self.rp.equalize_magnitude:
			self.connect((self.remove_pilot,1), (self.equalizer,1), (self,1))
		else:
			self.connect((self.remove_pilot,1), (self,1))
			
		# calculate an estimate of the SNR
		self.phase_var_decim   = gr.keep_one_in_n(gr.sizeof_gr_complex*self.dp.num_carriers, self.rp.phase_var_estimate_downsample)
		self.phase_var_arg     = gr.complex_to_arg(dp.num_carriers)
		self.phase_var_v2s     = gr.vector_to_stream(gr.sizeof_float, dp.num_carriers)
		self.phase_var_mod     = dab_swig.modulo_ff(pi/2)
		self.phase_var_avg_mod = gr.iir_filter_ffd([rp.phase_var_estimate_alpha], [0,1-rp.phase_var_estimate_alpha]) 
		self.phase_var_sub_avg = gr.sub_ff()
		self.phase_var_sqr     = gr.multiply_ff()
		self.phase_var_avg     = gr.iir_filter_ffd([rp.phase_var_estimate_alpha], [0,1-rp.phase_var_estimate_alpha]) 
		self.probe_phase_var   = gr.probe_signal_f()
		self.connect((self.remove_pilot,0), self.phase_var_decim, self.phase_var_arg, self.phase_var_v2s, self.phase_var_mod, (self.phase_var_sub_avg,0), (self.phase_var_sqr,0))
		self.connect(self.phase_var_mod, self.phase_var_avg_mod, (self.phase_var_sub_avg,1))
		self.connect(self.phase_var_sub_avg, (self.phase_var_sqr,1))
		self.connect(self.phase_var_sqr, self.phase_var_avg, self.probe_phase_var)

		# measure processing rate
		self.measure_rate = dab_swig.measure_processing_rate(gr.sizeof_gr_complex, 2000000) 
		self.connect(self.input, self.measure_rate)

		# debugging
		if debug:
			self.connect(self.fft, gr.file_sink(gr.sizeof_gr_complex*dp.fft_length, "debug/ofdm_after_fft.dat"))
			self.connect((self.cfs,0), gr.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_after_cfs.dat"))
			self.connect(self.phase_diff, gr.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_diff_phasor.dat"))
			self.connect((self.remove_pilot,0), gr.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_pilot_removed.dat"))
			self.connect((self.remove_pilot,1), gr.file_sink(gr.sizeof_char, "debug/ofdm_after_cfs_trigger.dat"))
			self.connect(self.deinterleave, gr.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_deinterleaved.dat"))
			if self.rp.equalize_magnitude:
				self.connect(self.equalizer, gr.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_equalizer.dat"))
			if self.rp.softbits:
				self.connect(self.softbit_interleaver, gr.file_sink(gr.sizeof_float*dp.num_carriers*2, "debug/softbits.dat"))
예제 #38
0
파일: bot1_rx.py 프로젝트: randyp1248/darpa
    def __init__(self, options):
        gr.top_block.__init__(self)

        if(options.rx_freq is not None):
	    symbol_rate = 500000
	    self.source = uhd_receiver(options.args, symbol_rate,
				       2,
				       options.rx_freq, 30,
				       #options.spec, "RX2",
				       options.spec, "TX/RX",
				       1) #options.verbose)
	    options.samples_per_symbol = self.source._sps

        elif(options.from_file is not None):
            sys.stderr.write(("Reading samples from '%s'.\n\n" % (options.from_file)))
            self.source = gr.file_source(gr.sizeof_gr_complex, options.from_file)
        else:
            sys.stderr.write("No source defined, pulling samples from null source.\n\n")
            self.source = gr.null_source(gr.sizeof_gr_complex)

        # Set up receive path
	# Correlator block
        self.correlator = correlator_cc.correlator_cc()

	# Despreader block
	self.despreader = spreader.despreader_cb()
  
        # RS Decoder block
	self.decoder = rscoding_bb.decode_bb()

        # CRC RX Block
        self.crcrx = crc.crcrx()

	# Packetizer receiver
	self.packetrx = packetizer.packet_sink()

	# Print block
	self.printer = print_bb.print_bb()

	# NULL sink block
        self.nullsink = gr.null_sink(1)
 
        # RRC filter
        #nfilts = 32 
        #ntaps = nfilts * 11 * int(options.samples_per_symbol)
        #self.rrc_taps = gr.firdes.root_raised_cosine(
            #1.0, # gain
            #1000000, # sampling rate based on 32 fliters in resampler
            #symbol_rate,    # symbol rate
            #1.0,    # excess bandwidth or roll-off factor
            #ntaps)
        #self.rrc_filter = gr.pfb_arb_resampler_ccf(options.samples_per_symbol, 
        #                                           self.rrc_taps)


        # Design filter to get actual channel we want
        sw_decim = 1
        chan_coeffs = gr.firdes.low_pass (1.0,                  # gain
                                          #sw_decim * self.samples_per_symbol(), # sampling rate
                                          #1000000, # sampling rate
                                          2,
                                          #self._chbw_factor,    # midpoint of trans. band
                                          1,    # midpoint of trans. band
                                          0.5,                  # width of trans. band
                                          gr.firdes.WIN_HANN)   # filter type
        self.channel_filter = gr.fft_filter_ccc(sw_decim, chan_coeffs)


	# Connect the blocks
        #self.connect(self.source, self.correlator)
        #self.connect(self.source, self.rrc_filter)
        #self.connect(self.rrc_filter, self.correlator)

        # connect block input to channel filter
	self.connect(self.source, self.channel_filter)
        self.connect(self.channel_filter, self.correlator)


        #self.connect(self.source, self.correlator)
        self.connect(self.correlator, self.despreader)
        self.connect(self.despreader, self.decoder)
        self.connect(self.decoder, self.crcrx)
        #self.connect(self.decoder, self.printer)
        #self.connect(self.printer, self.crcrx)
        #self.connect(self.despreader, self.printer)
        #self.connect(self.printer, self.nullsink)
        #self.connect(self.printer, self.filesink)
        #self.connect(self.crcrx, self.filesink)
        self.connect(self.crcrx, self.packetrx) 
예제 #39
0
    def __init__(self, demod_class, rx_callback, options):
        gr.hier_block2.__init__(self, "receive_path",
                                gr.io_signature(1, 1, gr.sizeof_gr_complex),
                                gr.io_signature(0, 0, 0))

        options = copy.copy(
            options)  # make a copy so we can destructively modify

        self._verbose = options.verbose
        self._bitrate = options.bitrate  # desired bit rate

        self._rx_callback = rx_callback  # this callback is fired when a packet arrives
        self._demod_class = demod_class  # the demodulator_class we're using

        self._chbw_factor = options.chbw_factor  # channel filter bandwidth factor

        # Get demod_kwargs
        demod_kwargs = self._demod_class.extract_kwargs_from_options(options)

        # Build the demodulator
        self.demodulator = self._demod_class(**demod_kwargs)

        # Make sure the channel BW factor is between 1 and sps/2
        # or the filter won't work.
        if (self._chbw_factor < 1.0
                or self._chbw_factor > self.samples_per_symbol() / 2):
            sys.stderr.write(
                "Channel bandwidth factor ({0}) must be within the range [1.0, {1}].\n"
                .format(self._chbw_factor,
                        self.samples_per_symbol() / 2))
            sys.exit(1)

    # Design filter to get actual channel we want
        sw_decim = 1
        chan_coeffs = gr.firdes.low_pass(
            1.0,  # gain
            sw_decim * self.samples_per_symbol(),  # sampling rate
            self._chbw_factor,  # midpoint of trans. band
            0.5,  # width of trans. band
            gr.firdes.WIN_HANN)  # filter type
        self.channel_filter = gr.fft_filter_ccc(sw_decim, chan_coeffs)

        # receiver
        self.packet_receiver = \
            digital.demod_pkts(self.demodulator,
                               access_code=None,
                               callback=self._rx_callback,
                               threshold=-1)

        # Carrier Sensing Blocks
        alpha = 0.001
        thresh = 30  # in dB, will have to adjust
        self.probe = gr.probe_avg_mag_sqrd_c(thresh, alpha)

        # Display some information about the setup
        if self._verbose:
            self._print_verbage()

        # connect block input to channel filter
        self.connect(self, self.channel_filter)

        # connect the channel input filter to the carrier power detector
        self.connect(self.channel_filter, self.probe)

        # connect channel filter to the packet receiver
        self.connect(self.channel_filter, self.packet_receiver)
예제 #40
0
    def __init__(self, fft_length, cp_length, kstime, threshold, threshold_type, threshold_gap, logging=False):
        """
        OFDM synchronization using PN Correlation:
        T. M. Schmidl and D. C. Cox, "Robust Frequency and Timing
        Synchonization for OFDM," IEEE Trans. Communications, vol. 45,
        no. 12, 1997.
        """
        
	gr.hier_block2.__init__(self, "ofdm_sync_pn",
				gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
                                gr.io_signature2(2, 2, gr.sizeof_float, gr.sizeof_char)) # Output signature

        self.input = gr.add_const_cc(0)

        # PN Sync

        # Create a delay line
        self.delay = gr.delay(gr.sizeof_gr_complex, fft_length/2)

        # Correlation from ML Sync
        self.conjg = gr.conjugate_cc();
        self.corr = gr.multiply_cc();

        # Create a moving sum filter for the corr output
        if 1:
            moving_sum_taps = [1.0 for i in range(fft_length//2)]
            self.moving_sum_filter = gr.fir_filter_ccf(1,moving_sum_taps)
        else:
            moving_sum_taps = [complex(1.0,0.0) for i in range(fft_length//2)]
            self.moving_sum_filter = gr.fft_filter_ccc(1,moving_sum_taps)

        # Create a moving sum filter for the input
        self.inputmag2 = gr.complex_to_mag_squared()
        movingsum2_taps = [1.0 for i in range(fft_length//2)]
	#movingsum2_taps = [0.5 for i in range(fft_length*4)]		#apurv - implementing Veljo's suggestion, when pause b/w packets

        if 1:
            self.inputmovingsum = gr.fir_filter_fff(1,movingsum2_taps)
        else:
            self.inputmovingsum = gr.fft_filter_fff(1,movingsum2_taps)

        self.square = gr.multiply_ff()
        self.normalize = gr.divide_ff()
     
        # Get magnitude (peaks) and angle (phase/freq error)
        self.c2mag = gr.complex_to_mag_squared()
        self.angle = gr.complex_to_arg()

        self.sample_and_hold = gr.sample_and_hold_ff()

        #ML measurements input to sampler block and detect
        self.sub1 = gr.add_const_ff(-1)
        self.pk_detect = gr.peak_detector_fb(0.20, 0.20, 30, 0.001)	#apurv - implementing Veljo's suggestion, when pause b/w packets

        self.connect(self, self.input)
        
        # Calculate the frequency offset from the correlation of the preamble
        self.connect(self.input, self.delay)
        self.connect(self.input, (self.corr,0))
        self.connect(self.delay, self.conjg)
        self.connect(self.conjg, (self.corr,1))


        self.connect(self.corr, self.moving_sum_filter)
        #self.connect(self.moving_sum_filter, self.c2mag)
        self.connect(self.moving_sum_filter, self.angle)
        self.connect(self.angle, (self.sample_and_hold,0))		# apurv--
	#self.connect(self.angle, gr.delay(gr.sizeof_float, offset), (self.sample_and_hold, 0))	#apurv++

	cross_correlate = 1
	if cross_correlate==1:
	   # cross-correlate with the known symbol
	   kstime = [k.conjugate() for k in kstime]
           kstime.reverse()
           self.crosscorr_filter = gr.fir_filter_ccc(1, kstime)

	   # get the magnitude #
	   self.corrmag = gr.complex_to_mag_squared()

	   self.f2b = gr.float_to_char()
	   self.threshold_factor = threshold #0.0012 #0.012   #0.0015
	   if 0:
	      self.slice = gr.threshold_ff(self.threshold_factor, self.threshold_factor, 0, fft_length)
	   else:
	      #thresholds = [self.threshold_factor, 9e-5]
	      self.slice = gr.threshold_ff(threshold, threshold, 0, fft_length, threshold_type, threshold_gap)

	   self.connect(self.input, self.crosscorr_filter, self.corrmag, self.slice, self.f2b)

	   # some debug dump #
	   self.connect(self.corrmag, gr.file_sink(gr.sizeof_float, "ofdm_corrmag.dat"))
	   #self.connect(self.f2b, gr.file_sink(gr.sizeof_char, "ofdm_f2b.dat"))
	   

	self.connect(self.f2b, (self.sample_and_hold,1))
	
        # Set output signals
        #    Output 0: fine frequency correction value
        #    Output 1: timing signal
        self.connect(self.sample_and_hold, (self,0))
	#self.connect(self.pk_detect, (self,1))									#removed
	#self.connect(self.f2b, gr.delay(gr.sizeof_char, 1), (self, 1))
	self.connect(self.f2b, (self, 1))

        if logging:
            self.connect(self.matched_filter, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-mf_f.dat"))
            self.connect(self.normalize, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-theta_f.dat"))
            self.connect(self.angle, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-epsilon_f.dat"))
            self.connect(self.pk_detect, gr.file_sink(gr.sizeof_char, "ofdm_sync_pn-peaks_b.dat"))
            self.connect(self.sample_and_hold, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-sample_and_hold_f.dat"))
            self.connect(self.input, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_pn-input_c.dat"))
예제 #41
0
def main():
    N = 10000
    fs = 2000.0
    Ts = 1.0 / fs
    t = scipy.arange(0, N * Ts, Ts)

    # When playing with the number of channels, be careful about the filter
    # specs and the channel map of the synthesizer set below.
    nchans = 10

    # Build the filter(s)
    bw = 1000
    tb = 400
    proto_taps = gr.firdes.low_pass_2(1, nchans * fs, bw, tb, 80,
                                      gr.firdes.WIN_BLACKMAN_hARRIS)
    print "Filter length: ", len(proto_taps)

    # Create a modulated signal
    npwr = 0.01
    data = scipy.random.randint(0, 256, N)
    rrc_taps = gr.firdes.root_raised_cosine(1, 2, 1, 0.35, 41)

    src = gr.vector_source_b(data.astype(scipy.uint8).tolist(), False)
    mod = digital.bpsk_mod(samples_per_symbol=2)
    chan = gr.channel_model(npwr)
    rrc = gr.fft_filter_ccc(1, rrc_taps)

    # Split it up into pieces
    channelizer = blks2.pfb_channelizer_ccf(nchans, proto_taps, 2)

    # Put the pieces back together again
    syn_taps = [nchans * t for t in proto_taps]
    synthesizer = gr.pfb_synthesizer_ccf(nchans, syn_taps, True)
    src_snk = gr.vector_sink_c()
    snk = gr.vector_sink_c()

    # Remap the location of the channels
    # Can be done in synth or channelizer (watch out for rotattions in
    # the channelizer)
    synthesizer.set_channel_map([0, 1, 2, 3, 4, 15, 16, 17, 18, 19])

    tb = gr.top_block()
    tb.connect(src, mod, chan, rrc, channelizer)
    tb.connect(rrc, src_snk)

    vsnk = []
    for i in xrange(nchans):
        tb.connect((channelizer, i), (synthesizer, i))

        vsnk.append(gr.vector_sink_c())
        tb.connect((channelizer, i), vsnk[i])

    tb.connect(synthesizer, snk)
    tb.run()

    sin = scipy.array(src_snk.data()[1000:])
    sout = scipy.array(snk.data()[1000:])

    # Plot original signal
    fs_in = nchans * fs
    f1 = pylab.figure(1, figsize=(16, 12), facecolor='w')
    s11 = f1.add_subplot(2, 2, 1)
    s11.psd(sin, NFFT=fftlen, Fs=fs_in)
    s11.set_title("PSD of Original Signal")
    s11.set_ylim([-200, -20])

    s12 = f1.add_subplot(2, 2, 2)
    s12.plot(sin.real[1000:1500], "o-b")
    s12.plot(sin.imag[1000:1500], "o-r")
    s12.set_title("Original Signal in Time")

    start = 1
    skip = 4
    s13 = f1.add_subplot(2, 2, 3)
    s13.plot(sin.real[start::skip], sin.imag[start::skip], "o")
    s13.set_title("Constellation")
    s13.set_xlim([-2, 2])
    s13.set_ylim([-2, 2])

    # Plot channels
    nrows = int(scipy.sqrt(nchans))
    ncols = int(scipy.ceil(float(nchans) / float(nrows)))

    f2 = pylab.figure(2, figsize=(16, 12), facecolor='w')
    for n in xrange(nchans):
        s = f2.add_subplot(nrows, ncols, n + 1)
        s.psd(vsnk[n].data(), NFFT=fftlen, Fs=fs_in)
        s.set_title("Channel {0}".format(n))
        s.set_ylim([-200, -20])

    # Plot reconstructed signal
    fs_out = 2 * nchans * fs
    f3 = pylab.figure(3, figsize=(16, 12), facecolor='w')
    s31 = f3.add_subplot(2, 2, 1)
    s31.psd(sout, NFFT=fftlen, Fs=fs_out)
    s31.set_title("PSD of Reconstructed Signal")
    s31.set_ylim([-200, -20])

    s32 = f3.add_subplot(2, 2, 2)
    s32.plot(sout.real[1000:1500], "o-b")
    s32.plot(sout.imag[1000:1500], "o-r")
    s32.set_title("Reconstructed Signal in Time")

    start = 2
    skip = 4
    s33 = f3.add_subplot(2, 2, 3)
    s33.plot(sout.real[start::skip], sout.imag[start::skip], "o")
    s33.set_title("Constellation")
    s33.set_xlim([-2, 2])
    s33.set_ylim([-2, 2])

    pylab.show()
예제 #42
0
    def __init__(self,
                 fft_length,
                 cp_length,
                 occupied_tones,
                 snr,
                 ks,
                 threshold,
                 options,
                 logging=False):
        """
	Hierarchical block for receiving OFDM symbols.

	The input is the complex modulated signal at baseband.
        Synchronized packets are sent back to the demodulator.

        @param fft_length: total number of subcarriers
        @type  fft_length: int
        @param cp_length: length of cyclic prefix as specified in subcarriers (<= fft_length)
        @type  cp_length: int
        @param occupied_tones: number of subcarriers used for data
        @type  occupied_tones: int
        @param snr: estimated signal to noise ratio used to guide cyclic prefix synchronizer
        @type  snr: float
        @param ks: known symbols used as preambles to each packet
        @type  ks: list of lists
        @param logging: turn file logging on or off
        @type  logging: bool
	"""

        gr.hier_block2.__init__(
            self,
            "ofdm_receiver",
            gr.io_signature(1, 1, gr.sizeof_gr_complex),  # Input signature
            #gr.io_signature2(2, 2, gr.sizeof_gr_complex*occupied_tones, gr.sizeof_char)) # Output signature apurv--
            gr.io_signature3(3, 3, gr.sizeof_gr_complex * occupied_tones,
                             gr.sizeof_char,
                             gr.sizeof_gr_complex * occupied_tones
                             ))  # apurv++, goes into frame sink for hestimates
        #gr.io_signature4(4, 4, gr.sizeof_gr_complex*occupied_tones, gr.sizeof_char, gr.sizeof_gr_complex*occupied_tones, gr.sizeof_gr_complex*fft_length))     # apurv++, goes into frame sink for hestimates

        bw = (float(occupied_tones) / float(fft_length)) / 2.0
        tb = bw * 0.08
        chan_coeffs = gr.firdes.low_pass(
            1.0,  # gain
            1.0,  # sampling rate
            bw + tb,  # midpoint of trans. band
            tb,  # width of trans. band
            gr.firdes.WIN_HAMMING)  # filter type
        self.chan_filt = gr.fft_filter_ccc(1, chan_coeffs)

        win = [1 for i in range(fft_length)]

        zeros_on_left = int(math.ceil((fft_length - occupied_tones) / 2.0))
        ks0 = fft_length * [
            0,
        ]
        ks0[zeros_on_left:zeros_on_left + occupied_tones] = ks[0]

        ks0 = fft.ifftshift(ks0)
        ks0time = fft.ifft(ks0)
        # ADD SCALING FACTOR
        ks0time = ks0time.tolist()

        nco_sensitivity = -2.0 / fft_length  # correct for fine frequency
        self.ofdm_sync = ofdm_sync_pn(fft_length, cp_length, ks0time,
                                      threshold, options.threshold_type,
                                      options.threshold_gap,
                                      logging)  # apurv++

        # Set up blocks

        self.nco = gr.frequency_modulator_fc(
            nco_sensitivity
        )  # generate a signal proportional to frequency error of sync block
        self.sigmix = gr.multiply_cc()
        self.sampler = digital_swig.ofdm_sampler(
            fft_length, fft_length + cp_length,
            len(ks) + 1, 100
        )  # 1 for the extra preamble which ofdm_rx doesn't know about (check frame_sink)
        self.fft_demod = gr.fft_vcc(fft_length, True, win, True)
        self.ofdm_frame_acq = digital_swig.ofdm_frame_acquisition(
            occupied_tones, fft_length, cp_length, ks)

        if options.verbose:
            self._print_verbage(options)

# apurv++ modified to allow collected time domain data to artifically pass through the rx chain #

# to replay the input manually, use this #
#self.connect(self, gr.null_sink(gr.sizeof_gr_complex))
#self.connect(gr.file_source(gr.sizeof_gr_complex, "input.dat"), self.chan_filt)

############# input -> chan_filt ##############
        self.connect(self, self.chan_filt)

        use_chan_filt = options.use_chan_filt
        correct_freq_offset = 0

        if use_chan_filt == 1:
            ##### chan_filt -> SYNC, chan_filt -> SIGMIX ####
            self.connect(self.chan_filt, self.ofdm_sync)
            if correct_freq_offset == 1:
                # enable if frequency offset correction is required #
                self.connect(self.chan_filt,
                             gr.delay(gr.sizeof_gr_complex, (fft_length)),
                             (self.sigmix, 0))  # apurv++ follow freq offset
            else:
                self.connect(self.chan_filt, (self.sampler, 0))
                ###self.connect(self.chan_filt, gr.delay(gr.sizeof_gr_complex, (fft_length)), (self.sampler, 0))		## extra delay

                #self.connect(self.chan_filt, gr.file_sink(gr.sizeof_gr_complex, "ofdm_receiver-chan_filt_c.dat"))
        elif use_chan_filt == 2:
            #### alternative: chan_filt-> NULL, file_source -> SYNC, file_source -> SIGMIX ####
            self.connect(self.chan_filt, gr.null_sink(gr.sizeof_gr_complex))
            if correct_freq_offset == 1:
                self.connect(
                    gr.file_source(gr.sizeof_gr_complex, "chan_filt.dat"),
                    self.ofdm_sync)
                self.connect(
                    gr.file_source(gr.sizeof_gr_complex, "chan_filt.dat"),
                    gr.delay(gr.sizeof_gr_complex, (fft_length)),
                    (self.sigmix, 0))
            else:
                self.connect(
                    gr.file_source(gr.sizeof_gr_complex, "chan_filt.dat"),
                    self.ofdm_sync)
                self.connect(
                    gr.file_source(gr.sizeof_gr_complex, "chan_filt.dat"),
                    (self.sampler, 0))
        else:
            # chan_filt->NULL #
            self.connect(self.chan_filt, gr.null_sink(gr.sizeof_gr_complex))

        method = options.method
        if method == -1:
            ################## for offline analysis, dump sampler input till the frame_sink, using io_signature4 #################
            if correct_freq_offset == 1:
                # enable if frequency offset correction is required #
                self.connect((self.ofdm_sync, 0), self.nco,
                             (self.sigmix, 1))  # freq offset (0'ed :/)
                self.connect(self.sigmix,
                             (self.sampler, 0))  # corrected output (0'ed FF)
                self.connect((self.ofdm_sync, 1),
                             gr.delay(gr.sizeof_char, fft_length),
                             (self.sampler, 1))  # timing signal

            else:
                # disable frequency offset correction completely #
                self.connect((self.ofdm_sync, 0),
                             gr.null_sink(gr.sizeof_float))
                self.connect((self.ofdm_sync, 1),
                             (self.sampler, 1))  # timing signal,

                #self.connect((self.ofdm_sync,0), (self.sampler, 2))						##added
                ##self.connect((self.ofdm_sync,1), gr.delay(gr.sizeof_char, fft_length+cp_length), (self.sampler, 1))           # timing signal, ##extra delay

                # route received time domain to sink (all-the-way) for offline analysis #
            self.connect((self.sampler, 0), (self.ofdm_frame_acq, 2))
            #self.connect((self.sampler, 1), gr.file_sink(gr.sizeof_char*fft_length, "sampler_timing.dat"))

        elif method == 0:
            # NORMAL functioning #
            if correct_freq_offset == 1:
                self.connect(
                    (self.ofdm_sync, 0), self.nco, (self.sigmix, 1)
                )  # use sync freq. offset output to derotate input signal
                self.connect(
                    self.sigmix,
                    (self.sampler,
                     0))  # sample off timing signal detected in sync alg
                self.connect((self.ofdm_sync, 1),
                             gr.delay(gr.sizeof_char, fft_length),
                             (self.sampler, 1))  # delay?
            else:
                self.connect((self.ofdm_sync, 1), (self.sampler, 1))

#self.connect((self.sampler, 2), (self.ofdm_frame_acq, 2))
#######################################################################

        use_default = options.use_default
        if use_default == 0:  #(set method == 0)
            # sampler-> NULL, replay trace->fft_demod, ofdm_frame_acq (time domain) #
            #self.connect((self.sampler, 0), gr.null_sink(gr.sizeof_gr_complex*fft_length))
            #self.connect((self.sampler, 1), gr.null_sink(gr.sizeof_char*fft_length))

            self.connect(
                gr.file_source(gr.sizeof_gr_complex * fft_length,
                               "symbols_src.dat"), self.fft_demod)
            self.connect(
                gr.file_source(gr.sizeof_char * fft_length, "timing_src.dat"),
                (self.ofdm_frame_acq, 1))
            self.connect(self.fft_demod, (self.ofdm_frame_acq, 0))
        elif use_default == 1:  #(set method == -1)
            # normal functioning #
            self.connect(
                (self.sampler, 0),
                self.fft_demod)  # send derotated sampled signal to FFT
            self.connect((self.sampler, 1),
                         (self.ofdm_frame_acq,
                          1))  # send timing signal to signal frame start
            self.connect(self.fft_demod, (self.ofdm_frame_acq, 0))
        elif use_default == 2:
            # replay directly to ofdm_frame_acq (frequency domain) #
            self.connect(
                gr.file_source(gr.sizeof_gr_complex * fft_length,
                               "symbols_src.dat"), (self.ofdm_frame_acq, 0))
            self.connect(
                gr.file_source(gr.sizeof_char * fft_length, "timing_src.dat"),
                (self.ofdm_frame_acq, 1))

########################### some logging start ##############################
#self.connect((self.ofdm_sync,1), gr.delay(gr.sizeof_char, fft_length), gr.file_sink(gr.sizeof_char, "ofdm_sync_pn-peaks_b.dat"))
#self.connect((self.sampler, 0), gr.file_sink(gr.sizeof_gr_complex*fft_length, "ofdm_receiver-sampler_c.dat"))
#self.connect((self.sampler, 1), gr.file_sink(gr.sizeof_char*fft_length, "ofdm_timing_sampler_c.dat"))
############################ some logging end ###############################

        self.connect((self.ofdm_frame_acq, 0),
                     (self, 0))  # finished with fine/coarse freq correction,
        self.connect((self.ofdm_frame_acq, 1),
                     (self, 1))  # frame and symbol timing, and equalization
        self.connect((self.ofdm_frame_acq, 2),
                     (self, 2))  # equalizer: hestimates

        #self.connect((self.ofdm_frame_acq,3), (self,3))           # ref sampler above

        # apurv++ ends #

        #self.connect(self.ofdm_frame_acq, gr.file_sink(gr.sizeof_gr_complex*occupied_tones, "ofdm_receiver-frame_acq_c.dat"))
        #self.connect((self.ofdm_frame_acq,1), gr.file_sink(1, "ofdm_receiver-found_corr_b.dat"))

        # apurv++ log the fine frequency offset corrected symbols #
        #self.connect((self.ofdm_frame_acq, 1), gr.file_sink(gr.sizeof_char, "ofdm_timing_frame_acq_c.dat"))
        #self.connect((self.ofdm_frame_acq, 2), gr.file_sink(gr.sizeof_gr_complex*occupied_tones, "ofdm_hestimates_c.dat"))
        #self.connect(self.fft_demod, gr.file_sink(gr.sizeof_gr_complex*fft_length, "ofdm_receiver-fft_out_c.dat"))
        #self.connect(self.chan_filt, gr.file_sink(gr.sizeof_gr_complex, "ofdm_receiver-chan_filt_c.dat"))
        #self.connect(self, gr.file_sink(gr.sizeof_gr_complex, "ofdm_input_c.dat"))
        # apurv++ end #

        if logging:
            self.connect(
                self.chan_filt,
                gr.file_sink(gr.sizeof_gr_complex,
                             "ofdm_receiver-chan_filt_c.dat"))
            self.connect(
                self.fft_demod,
                gr.file_sink(gr.sizeof_gr_complex * fft_length,
                             "ofdm_receiver-fft_out_c.dat"))
            self.connect(
                self.ofdm_frame_acq,
                gr.file_sink(gr.sizeof_gr_complex * occupied_tones,
                             "ofdm_receiver-frame_acq_c.dat"))
            self.connect((self.ofdm_frame_acq, 1),
                         gr.file_sink(1, "ofdm_receiver-found_corr_b.dat"))
            self.connect(
                self.sampler,
                gr.file_sink(gr.sizeof_gr_complex * fft_length,
                             "ofdm_receiver-sampler_c.dat"))
            #self.connect(self.sigmix, gr.file_sink(gr.sizeof_gr_complex, "ofdm_receiver-sigmix_c.dat"))
            self.connect(
                self.nco,
                gr.file_sink(gr.sizeof_gr_complex, "ofdm_receiver-nco_c.dat"))
예제 #43
0
    def __init__(self, demod_class, rx_callback, options):

	gr.hier_block2.__init__(self, "receive_path",
                                gr.io_signature(0, 0, 0), # Input signature
                                gr.io_signature(0, 0, 0)) # Output signature

        options = copy.copy(options)    # make a copy so we can destructively modify

        self._verbose            = options.verbose
        self._rx_freq            = options.rx_freq         # receiver's center frequency
        self._rx_gain            = options.rx_gain         # receiver's gain
        self._rx_subdev_spec     = options.rx_subdev_spec  # daughterboard to use
        self._bitrate            = options.bitrate         # desired bit rate
        self._decim              = options.decim           # Decimating rate for the USRP (prelim)
        self._samples_per_symbol = options.samples_per_symbol  # desired samples/symbol
        self._fusb_block_size    = options.fusb_block_size # usb info for USRP
        self._fusb_nblocks       = options.fusb_nblocks    # usb info for USRP

        self._rx_callback   = rx_callback      # this callback is fired when there's a packet available
        self._demod_class   = demod_class      # the demodulator_class we're using

        if self._rx_freq is None:
            sys.stderr.write("-f FREQ or --freq FREQ or --rx-freq FREQ must be specified\n")
            raise SystemExit

        # Set up USRP source; also adjusts decim, samples_per_symbol, and bitrate
        self._setup_usrp_source()

        g = self.subdev.gain_range()
        if options.show_rx_gain_range:
            print "Rx Gain Range: minimum = %g, maximum = %g, step size = %g" \
                  % (g[0], g[1], g[2])

        self.set_gain(options.rx_gain)

        self.set_auto_tr(True)                 # enable Auto Transmit/Receive switching

        # Set RF frequency
        ok = self.set_freq(self._rx_freq)
        if not ok:
            print "Failed to set Rx frequency to %s" % (eng_notation.num_to_str(self._rx_freq))
            raise ValueError, eng_notation.num_to_str(self._rx_freq)

        # copy the final answers back into options for use by demodulator
        options.samples_per_symbol = self._samples_per_symbol
        options.bitrate = self._bitrate
        options.decim = self._decim

        # Get demod_kwargs
        demod_kwargs = self._demod_class.extract_kwargs_from_options(options)

        # Design filter to get actual channel we want
        sw_decim = 1
        chan_coeffs = gr.firdes.low_pass (1.0,                  # gain
                                          sw_decim * self._samples_per_symbol, # sampling rate
                                          1.0,                  # midpoint of trans. band
                                          0.5,                  # width of trans. band
                                          gr.firdes.WIN_HANN)   # filter type 

        # Decimating channel filter
        # complex in and out, float taps
        self.chan_filt = gr.fft_filter_ccc(sw_decim, chan_coeffs)
        #self.chan_filt = gr.fir_filter_ccf(sw_decim, chan_coeffs)

        # receiver
        self.packet_receiver = \
            blks2.demod_pkts(self._demod_class(**demod_kwargs),
                             access_code=None,
                             callback=self._rx_callback,
                             threshold=-1)
    
        # Carrier Sensing Blocks
        alpha = 0.001
        thresh = 30   # in dB, will have to adjust

        self.sequelcher = gr.simple_squelch_cc(45)
        if options.log_rx_power == True:
            self.probe = gr.probe_avg_mag_sqrd_cf(thresh,alpha)
            self.power_sink = gr.file_sink(gr.sizeof_float, "rxpower.dat")
            self.connect(self.chan_filt, self.probe, self.power_sink)
        else:
            self.probe = gr.probe_avg_mag_sqrd_c(thresh,alpha)
            #self.connect(self.chan_filt, self.sequelcher, self.probe)

        # Display some information about the setup
        if self._verbose:
            self._print_verbage()
            
         #filter the noise and pass only the transmitted data
        
        #file_source = gr.file_source(gr.sizeof_gr_complex,"modulated_data.dat")
        #self.connect(self.chan_filt,file_sink)
        self.connect(self.u, self.chan_filt,self.sequelcher, self.packet_receiver)
예제 #44
0
    def __init__(self, demod_class, rx_callback, options, log_index=-1, use_new_pkt=False):
        gr.hier_block2.__init__(self, "receive_path",
    			gr.io_signature(1, 1, gr.sizeof_gr_complex),
    			gr.io_signature(0, 0, 0))
        
        options = copy.copy(options)    # make a copy so we can destructively modify
    
        self._verbose     = options.verbose
        self._bitrate     = options.modulation_bitrate  # desired bit rate
    
        self._rx_callback = rx_callback  # this callback is fired when a packet arrives
        self._demod_class = demod_class  # the demodulator_class we're using
    
        self._chbw_factor = options.chbw_factor # channel filter bandwidth factor
    
        self._access_code   = options.rx_access_code
        self._threshold     = options.access_code_threshold
    
        
        
        if  self._access_code == '0':
            self._access_code = None
        elif self._access_code == '1':
            self._access_code = '0000010000110001010011110100011100100101101110110011010101111110'
            print 'rx access code: %s' % self._access_code
        elif self._access_code == '2':
            self._access_code = '1110001100101100010110110001110101100000110001011101000100001110'
    
        # Get demod_kwargs
        demod_kwargs = self._demod_class.extract_kwargs_from_options(options)
    
        # Build the demodulator
        self.demodulator = self._demod_class(**demod_kwargs)
        print self.demodulator

        self._use_coding = False
        
        self._rfcenterfreq = options.rf_rx_freq
        
        # make sure option exists before adding member variable
        if hasattr(options, 'my_bandwidth'):
            self._bandwidth  = options.my_bandwidth
            
        self._logging    = lincolnlog.LincolnLog(__name__)
        #if options.pcktlog != -1:
        #    self._logging    = lincolnlog.LincolnLog(__name__)
        #else:
        #    self._logging = -1
    
        # Make sure the channel BW factor is between 1 and sps/2
        # or the filter won't work.
        if(self._chbw_factor < 1.0 or self._chbw_factor > self.samples_per_symbol()/2):
            sys.stderr.write("Channel bandwidth factor ({0}) must be within the range [1.0, {1}].\n".format(self._chbw_factor, self.samples_per_symbol()/2))
            sys.exit(1)
        
        # Design filter to get actual channel we want
        sw_decim = 1
        chan_coeffs = gr.firdes.low_pass (1.0,                  # gain
                                          sw_decim * self.samples_per_symbol(), # sampling rate
                                          self._chbw_factor,    # midpoint of trans. band
                                          0.5,                  # width of trans. band
                                          gr.firdes.WIN_HANN)   # filter type
        self.channel_filter = gr.fft_filter_ccc(sw_decim, chan_coeffs)
        
        # receiver
        self.packet_receiver = \
            digital_ll.pkt2.demod_pkts(self.demodulator, options, #added on 9/28/12
                               access_code=self._access_code,
                               callback=self._rx_callback,
                               threshold=self._threshold,
                               use_coding=self._use_coding,
                               logging=self._logging)

    
        # Display some information about the setup
        if self._verbose:
            self._print_verbage()
    
        # connect block input to channel filter
        self.connect(self, self.channel_filter)
    
        # connect channel filter to the packet receiver
        self.connect(self.channel_filter, self.packet_receiver)
        
       
            
        # added to make logging easier
        self._modulation = options.modulation 
        
        if "_constellation" in vars(self.demodulator):
            self._constellation_points = len(self.demodulator._constellation.points())
        else:
            self._constellation_points = None
            
        if "_excess_bw" in vars(self.demodulator):
            self._excess_bw = self.demodulator._excess_bw
        else:
            self._excess_bw = None
        
        if "_freq_bw" in vars(self.demodulator):
            self._freq_bw = self.demodulator._freq_bw
        else:
            self._freq_bw = None
            
        if "_phase_bw" in vars(self.demodulator):
            self._phase_bw = self.demodulator._phase_bw
        else:
            self._phase_bw = None
            
        if "_timing_bw" in vars(self.demodulator):
            self._timing_bw = self.demodulator._timing_bw
        else:
            self._timing_bw = None             
    def __init__(self, fg, mpoints, taps=None):
        """
        Takes M complex streams in, produces single complex stream out
        that runs at M times the input sample rate

        @param fg:      flow_graph
        @param mpoints: number of freq bins/interpolation factor/subbands
        @param taps:    filter taps for subband filter

        The channel spacing is equal to the input sample rate.
        The total bandwidth and output sample rate are equal the input
        sample rate * nchannels.

        Output stream to frequency mapping:
        
          channel zero is at zero frequency.

          if mpoints is odd:
            
            Channels with increasing positive frequencies come from
            channels 1 through (N-1)/2.

            Channel (N+1)/2 is the maximum negative frequency, and
            frequency increases through N-1 which is one channel lower
            than the zero frequency.

          if mpoints is even:

            Channels with increasing positive frequencies come from
            channels 1 through (N/2)-1.

            Channel (N/2) is evenly split between the max positive and
            negative bins.

            Channel (N/2)+1 is the maximum negative frequency, and
            frequency increases through N-1 which is one channel lower
            than the zero frequency.

            Channels near the frequency extremes end up getting cut
            off by subsequent filters and therefore have diminished
            utility.
        """
        item_size = gr.sizeof_gr_complex

        if taps is None:
            taps = _generate_synthesis_taps(mpoints)

        # pad taps to multiple of mpoints
        r = len(taps) % mpoints
        if r != 0:
            taps = taps + (mpoints - r) * (0,)

        # split in mpoints separate set of taps
        sub_taps = _split_taps(taps, mpoints)

        self.ss2v = gr.streams_to_vector(item_size, mpoints)
        self.ifft = gr.fft_vcc(mpoints, False, [])
        self.v2ss = gr.vector_to_streams(item_size, mpoints)
        # mpoints filters go in here...
        self.ss2s = gr.streams_to_stream(item_size, mpoints)

        fg.connect(self.ss2v, self.ifft, self.v2ss)

        # build mpoints fir filters...
        for i in range(mpoints):
            f = gr.fft_filter_ccc(1, sub_taps[i])
            fg.connect((self.v2ss, i), f)
            fg.connect(f, (self.ss2s, i))

        gr.hier_block.__init__(self, fg, self.ss2v, self.ss2s)
    def __init__(self, modulator_class, options):
        '''
        See below for what options should hold
        '''
	gr.hier_block2.__init__(self, "transmit_path",
				gr.io_signature(0,0,0),
				gr.io_signature(1,1,gr.sizeof_gr_complex))
        
        options = copy.copy(options)    # make a copy so we can destructively modify

        self._verbose      = options.verbose
        self._tx_amplitude = options.tx_amplitude   # digital amplitude sent to USRP
        self._bitrate      = options.bitrate        # desired bit rate
        self._modulator_class = modulator_class     # the modulator_class we are using

        # Get mod_kwargs
        mod_kwargs = self._modulator_class.extract_kwargs_from_options(options)
        
        # transmitter
	self.modulator = self._modulator_class(**mod_kwargs)
        
        self.packet_transmitter = \
            digital.mod_pkts(self.modulator,
                             access_code=None,
                             msgq_limit=4,
                             pad_for_usrp=True)

        self.amp = gr.multiply_const_cc(1)
        self.set_tx_amplitude(self._tx_amplitude)

        # Figure out how to calculate symbol_rate later
        symbol_rate = 5000000

        # Hardcoding rx_freq and rx_gain
	self.source = uhd_receiver(options.args, symbol_rate,
				   options.samples_per_symbol,
				   options.tx_freq-1250000, 30, 
				   options.spec, options.antenna,
				   options.verbose)
	options.samples_per_symbol = self.source._sps

        # Display some information about the setup
        if self._verbose:
            self._print_verbage()

        low_pass_taps = [
	   -0.0401, 
	    0.0663, 
	    0.0468, 
	   -0.0235, 
	   -0.0222, 
	    0.0572, 
	    0.0299, 
	   -0.1001, 
	   -0.0294, 
	    0.3166, 
	    0.5302, 
	    0.3166, 
	   -0.0294, 
	   -0.1001, 
	    0.0299, 
	    0.0572, 
	   -0.0222, 
	   -0.0235, 
	    0.0468, 
	    0.0663,
	   -0.0401]

        high_pass_taps = [
	   -0.0389,
	   -0.0026, 
	    0.0302, 
	    0.0181,
	   -0.0357,
	   -0.0394,
	    0.0450,
	    0.0923,
	   -0.0472,
	   -0.3119,
	    0.5512,
	   -0.3119,
	   -0.0472,
	    0.0923,
	    0.0450,
	   -0.0394,
	   -0.0357,
	    0.0181,
	    0.0302,
	   -0.0026,
	   -0.0389]

        # Carrier Sensing Blocks
        alpha = 0.001
        thresh = 30   # in dB, will have to adjust
        self.probe_lp = gr.probe_avg_mag_sqrd_c(thresh,alpha)
        self.probe_hp = gr.probe_avg_mag_sqrd_c(thresh,alpha)

        self.lp = gr.fft_filter_ccc(65536, low_pass_taps)
        self.hp = gr.fft_filter_ccc(65536, high_pass_taps)

        self.connect(self.source, self.lp)
        self.connect(self.lp, self.probe_lp)

        self.connect(self.source, self.hp)
        self.connect(self.hp, self.probe_hp)

        # Connect components in the flowgraph
        self.connect(self.packet_transmitter, self.amp, self)