示例#1
0
    def __init__(self, length, debug=False):
        """
        Hierarchical block to detect Null symbols

        @param length length of the Null symbol (in samples)
        @param debug whether to write signals out to files
        """
        gr.hier_block2.__init__(self, "detect_null",
                                gr.io_signature(1, 1, gr.sizeof_gr_complex),    # input signature
                                gr.io_signature(1, 1, gr.sizeof_char))          # output signature


        # get the magnitude squared
        self.ns_c2magsquared = gr.complex_to_mag_squared()
        self.ns_moving_sum = dabp.moving_sum_ff(length)
        self.ns_invert = gr.multiply_const_ff(-1)

        # peak detector on the inverted, summed up signal -> we get the nulls (i.e. the position of the start of a frame)
        self.ns_peak_detect = gr.peak_detector_fb(0.6,0.7,10,0.0001) # mostly found by try and error -> remember that the values are negative!

        # connect it all
        self.connect(self, self.ns_c2magsquared, self.ns_moving_sum, self.ns_invert, self.ns_peak_detect, self)

        if debug:
            self.connect(self.ns_invert, gr.file_sink(gr.sizeof_float, "debug/ofdm_sync_dabp_ns_filter_inv_f.dat"))
            self.connect(self.ns_peak_detect,gr.file_sink(gr.sizeof_char, "debug/ofdm_sync_dabp_peak_detect_b.dat"))
示例#2
0
    def __init__(self,options,Freq):
	gr.top_block.__init__(self)
	if options.input_file == "":
	    self.IS_USRP2 = True
	else:
	    self.IS_USRP2 = False
	#self.min_freq = options.start
	#self.max_freq = options.stop
	self.min_freq = Freq.value-(3*10**6) # same as that of the transmitter bandwidth ie 6MHZ approx for a given value of decimation line option any more
	self.max_freq = Freq.value+(3*10**6)
	if self.min_freq > self.max_freq:
	    self.min_freq, self.max_freq = self.max_freq, self.min_freq # swap them
	    print "Start and stop frequencies order swapped!"
	self.fft_size = options.fft_size
	self.ofdm_bins = options.sense_bins
	# build graph
	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)
	#log = gr.nlog10_ff(10, self.fft_size, -20*math.log10(self.fft_size)-10*math.log10(power/self.fft_size))
	# modifications for USRP2 
	if self.IS_USRP2:	
	    self.u = uhd.usrp_source(options.args,uhd.io_type.COMPLEX_FLOAT32,num_channels=1)		# Modified Line
	    # self.u.set_decim(options.decim)
	    # samp_rate = self.u.adc_rate()/self.u.decim()
	    samp_rate = 100e6/options.decim		# modified sampling rate
	    self.u.set_samp_rate(samp_rate)
	else:
	    self.u = gr.file_source(gr.sizeof_gr_complex,options.input_file, True)
	    samp_rate = 100e6 /options.decim		# modified sampling rate

	self.freq_step =0 #0.75* samp_rate
	self.min_center_freq = (self.min_freq + self.max_freq)/2
	
	global BW
	BW = self.max_freq - self.min_freq
	global size
	size=self.fft_size
	global ofdm_bins
	ofdm_bins = self.ofdm_bins
	global usr
	#global thrshold_inorder
	usr=samp_rate
	nsteps = 10 #math.ceil((self.max_freq - self.min_freq) / self.freq_step)
	self.max_center_freq = self.min_center_freq + (nsteps * self.freq_step)
	self.next_freq = self.min_center_freq
	tune_delay = max(0, int(round(options.tune_delay * samp_rate / self.fft_size))) # in fft_frames
	dwell_delay = max(1, int(round(options.dwell_delay * samp_rate / self.fft_size))) # in fft_frames
	self.msgq = gr.msg_queue(16)					# thread-safe message queue
	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)			# control scanning and record frequency domain statistics
	self.connect(self.u, s2v, fft,c2mag,stats)
	if options.gain is None:
	    g = self.u.get_gain_range()
	    options.gain = float(g.start()+g.stop())/2			# if no gain was specified, use the mid-point in dB
    def __init__(self, uhd_address, options):

        gr.top_block.__init__(self)

        self.uhd_addr = uhd_address
        self.freq = options.freq
        self.samp_rate = options.samp_rate
        self.gain = options.gain
        self.threshold = options.threshold
        self.trigger = options.trigger

        self.uhd_src = uhd.single_usrp_source(
            device_addr=self.uhd_addr, stream_args=uhd.stream_args('fc32'))

        self.uhd_src.set_samp_rate(self.samp_rate)
        self.uhd_src.set_center_freq(self.freq, 0)
        self.uhd_src.set_gain(self.gain, 0)

        taps = firdes.low_pass_2(1, 1, 0.4, 0.1, 60)
        self.chanfilt = gr.fir_filter_ccc(10, taps)
        self.tagger = gr.burst_tagger(gr.sizeof_gr_complex)

        # Dummy signaler to collect a burst on known periods
        data = 1000 * [
            0,
        ] + 1000 * [
            1,
        ]
        self.signal = gr.vector_source_s(data, True)

        # Energy detector to get signal burst
        ## use squelch to detect energy
        self.det = gr.simple_squelch_cc(self.threshold, 0.01)
        ## convert to mag squared (float)
        self.c2m = gr.complex_to_mag_squared()
        ## average to debounce
        self.avg = gr.single_pole_iir_filter_ff(0.01)
        ## rescale signal for conversion to short
        self.scale = gr.multiply_const_ff(2**16)
        ## signal input uses shorts
        self.f2s = gr.float_to_short()

        # Use file sink burst tagger to capture bursts
        self.fsnk = gr.tagged_file_sink(gr.sizeof_gr_complex, self.samp_rate)

        ##################################################
        # Connections
        ##################################################
        self.connect((self.uhd_src, 0), (self.tagger, 0))
        self.connect((self.tagger, 0), (self.fsnk, 0))

        if self.trigger:
            # Connect a dummy signaler to the burst tagger
            self.connect((self.signal, 0), (self.tagger, 1))

        else:
            # Connect an energy detector signaler to the burst tagger
            self.connect(self.uhd_src, self.det)
            self.connect(self.det, self.c2m, self.avg, self.scale, self.f2s)
            self.connect(self.f2s, (self.tagger, 1))
示例#4
0
	def setup_normal(self, setimode):
		
		self.setup_radiometer_common(1)
		
		self.head = self.u
		if (self.use_notches == True):
			self.shead = self.notch_filt
		else:
			self.shead = self.u
		
		if setimode == False:
				
			self.detector = gr.complex_to_mag_squared()
			self.connect(self.shead, self.scope)

			if (self.use_notches == False):
				self.connect(self.head, self.detector, self.mute, self.reference_level,
					self.integrator, self.keepn, self.cal_mult, self.cal_offs, self.chart)
			else:
				self.connect(self.head, self.notch_filt, self.detector, self.mute, self.reference_level,
					self.integrator, self.keepn, self.cal_mult, self.cal_offs, self.chart)
				
			self.connect(self.cal_offs, self.probe)
			
			#
			# Add a side-chain detector chain, with a different integrator, for sampling
			#   The reference channel data
			# This is used to derive the offset value for self.reference_level, used above
			#
			if (self.switch_mode == True):		
				self.connect(self.detector, self.cmute, self.cintegrator, self.swkeep, self.cprobe)
			
		return
示例#5
0
	def __init__(self, length, debug=False):
		"""
		Hierarchical block to detect Null symbols

		@param length length of the Null symbol (in samples)
		@param debug whether to write signals out to files
		"""
		gr.hier_block2.__init__(self,"detect_null",
		                        gr.io_signature(1, 1, gr.sizeof_gr_complex),    # input signature
					gr.io_signature(1, 1, gr.sizeof_char))          # output signature


		# get the magnitude squared
		self.ns_c2magsquared = gr.complex_to_mag_squared()
		
		# this wastes cpu cycles:
		# ns_detect_taps = [1]*length
		# self.ns_moving_sum = gr.fir_filter_fff(1,ns_detect_taps)
		# this isn't better:
		#self.ns_filter = gr.iir_filter_ffd([1]+[0]*(length-1)+[-1],[0,1])
		# this does the same again, but is actually faster (outsourced to an independent block ..):
		self.ns_moving_sum = dab_swig.moving_sum_ff(length)
		self.ns_invert = gr.multiply_const_ff(-1)

		# peak detector on the inverted, summed up signal -> we get the nulls (i.e. the position of the start of a frame)
		self.ns_peak_detect = gr.peak_detector_fb(0.6,0.7,10,0.0001) # mostly found by try and error -> remember that the values are negative!

		# connect it all
		self.connect(self, self.ns_c2magsquared, self.ns_moving_sum, self.ns_invert, self.ns_peak_detect, self)

		if debug:
			self.connect(self.ns_invert, gr.file_sink(gr.sizeof_float, "debug/ofdm_sync_dab_ns_filter_inv_f.dat"))
			self.connect(self.ns_peak_detect,gr.file_sink(gr.sizeof_char, "debug/ofdm_sync_dab_peak_detect_b.dat"))
示例#6
0
    def __init__(self, uhd_address, options):

        gr.top_block.__init__(self)

        self.uhd_addr = uhd_address
        self.freq = options.freq
        self.samp_rate = options.samp_rate
        self.gain = options.gain
        self.threshold = options.threshold
        self.trigger = options.trigger
        
        self.uhd_src = uhd.single_usrp_source(
            device_addr=self.uhd_addr,
            io_type=uhd.io_type_t.COMPLEX_FLOAT32,
            num_channels=1,
            )
        
        self.uhd_src.set_samp_rate(self.samp_rate)
        self.uhd_src.set_center_freq(self.freq, 0)
        self.uhd_src.set_gain(self.gain, 0)

        taps = firdes.low_pass_2(1, 1, 0.4, 0.1, 60)
        self.chanfilt = gr.fir_filter_ccc(10, taps)
        self.tagger = gr.burst_tagger(gr.sizeof_gr_complex)

        # Dummy signaler to collect a burst on known periods
        data = 1000*[0,] + 1000*[1,]
        self.signal = gr.vector_source_s(data, True)

        # Energy detector to get signal burst
        ## use squelch to detect energy
        self.det  = gr.simple_squelch_cc(self.threshold, 0.01)
        ## convert to mag squared (float)
        self.c2m = gr.complex_to_mag_squared()
        ## average to debounce
        self.avg = gr.single_pole_iir_filter_ff(0.01)
        ## rescale signal for conversion to short
        self.scale = gr.multiply_const_ff(2**16)
        ## signal input uses shorts
        self.f2s = gr.float_to_short()

        # Use file sink burst tagger to capture bursts
        self.fsnk = gr.tagged_file_sink(gr.sizeof_gr_complex, self.samp_rate)
        

        ##################################################
        # Connections
        ##################################################
        self.connect((self.uhd_src, 0), (self.tagger, 0))
        self.connect((self.tagger, 0), (self.fsnk, 0))

        if self.trigger:
            # Connect a dummy signaler to the burst tagger
            self.connect((self.signal, 0), (self.tagger, 1))

        else:
            # Connect an energy detector signaler to the burst tagger
            self.connect(self.uhd_src, self.det)
            self.connect(self.det, self.c2m, self.avg, self.scale, self.f2s)
            self.connect(self.f2s, (self.tagger, 1))
示例#7
0
def ms_to_file(hb, block, filename, N=4096, delay=0, fft=False, scale=1):
    streamsize = determine_streamsize(block)
    vlen = streamsize / gr.sizeof_gr_complex

    blks = [block]

    if fft and vlen > 1:
        gr_fft = fft_blocks.fft_vcc(vlen, True, [], True)
        blks.append(gr_fft)

    mag_sqrd = gr.complex_to_mag_squared(vlen)
    blks.append(mag_sqrd)

    if vlen > 1:
        v2s = blocks.vector_to_stream(gr.sizeof_float, vlen)
        blks.append(v2s)

    if delay != 0:
        delayline = delayline_ff(delay)
        blks.append(delayline)

    gr_scale = gr.multiply_const_ff(scale)
    blks.append(gr_scale)

    filter = gr.fir_filter_fff(1, [1.0 / N] * N)
    blks.append(filter)

    for i in range(len(blks) - 1):
        hb.connect(blks[i], blks[i + 1])

    log_to_file(hb, filter, filename)
示例#8
0
	def __init__(self, queue, options, args):
		#grc_wxgui.top_block_gui.__init__(self, title="Top Block")
		gr.top_block.__init__(self)
		##################################################
		# Variables
		##################################################
		self.samp_rate = samp_rate = 100e6/512

		##################################################
		# Blocks
		##################################################
		self.gr_complex_to_mag_squared_0 = gr.complex_to_mag_squared(1)
		self.gr_keep_one_in_n_0 = gr.keep_one_in_n(gr.sizeof_gr_complex*1, 10)
		self.keyfob_msg = keyfob.msg(queue, samp_rate/10.0, options.threshold)
		self.uhd_single_usrp_source_0 = uhd.single_usrp_source(
			device_addr="",
			io_type=uhd.io_type_t.COMPLEX_FLOAT32,
			num_channels=1,
		)
		_clk_cfg = uhd.clock_config_t()
		_clk_cfg.ref_source = uhd.clock_config_t.REF_SMA
		_clk_cfg.pps_source = uhd.clock_config_t.PPS_SMA
		_clk_cfg.pps_polarity = uhd.clock_config_t.PPS_POS
		#self.uhd_single_usrp_source_0.set_clock_config(_clk_cfg);
		self.uhd_single_usrp_source_0.set_samp_rate(samp_rate)
		self.uhd_single_usrp_source_0.set_center_freq(options.freq, 0)
		self.uhd_single_usrp_source_0.set_gain(40, 0)

		##################################################
		# Connections
		##################################################
		self.connect((self.uhd_single_usrp_source_0, 0), (self.gr_keep_one_in_n_0, 0))
		self.connect((self.gr_keep_one_in_n_0, 0), (self.gr_complex_to_mag_squared_0, 0))
		self.connect((self.gr_complex_to_mag_squared_0, 0), self.keyfob_msg)
    def __init__(self,options,Freq):
	gr.top_block.__init__(self)
	if options.input_file == "":
	    self.IS_USRP2 = True
	else:
	    self.IS_USRP2 = False
	#self.min_freq = options.start
	#self.max_freq = options.stop
	self.min_freq = Freq.value-(3*10**6) # same as that of the transmitter bandwidth ie 6MHZ approx for a given value of decimation line option any more
	self.max_freq = Freq.value+(3*10**6)
	if self.min_freq > self.max_freq:
	    self.min_freq, self.max_freq = self.max_freq, self.min_freq # swap them
	    print "Start and stop frequencies order swapped!"
	self.fft_size = options.fft_size
	self.ofdm_bins = options.sense_bins
	# build graph
	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)
	#log = gr.nlog10_ff(10, self.fft_size, -20*math.log10(self.fft_size)-10*math.log10(power/self.fft_size))
	# modifications for USRP2 
	if self.IS_USRP2:	
	    self.u = uhd.usrp_source(options.args,uhd.io_type.COMPLEX_FLOAT32,num_channels=1)		# Modified Line
	    # self.u.set_decim(options.decim)
	    # samp_rate = self.u.adc_rate()/self.u.decim()
	    samp_rate = 100e6/options.decim		# modified sampling rate
	    self.u.set_samp_rate(samp_rate)
	else:
	    self.u = gr.file_source(gr.sizeof_gr_complex,options.input_file, True)
	    samp_rate = 100e6 /options.decim		# modified sampling rate

	self.freq_step =0 #0.75* samp_rate
	self.min_center_freq = (self.min_freq + self.max_freq)/2
	
	global BW
	BW = self.max_freq - self.min_freq
	global size
	size=self.fft_size
	global ofdm_bins
	ofdm_bins = self.ofdm_bins
	global usr
	#global thrshold_inorder
	usr=samp_rate
	nsteps = 10 
	self.max_center_freq = self.min_center_freq + (nsteps * self.freq_step)
	self.next_freq = self.min_center_freq
	tune_delay = max(0, int(round(options.tune_delay * samp_rate / self.fft_size))) # in fft_frames
	dwell_delay = max(1, int(round(options.dwell_delay * samp_rate / self.fft_size))) # in fft_frames
	self.msgq = gr.msg_queue(16)					# thread-safe message queue
	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)			# control scanning and record frequency domain statistics
	self.connect(self.u, s2v, fft,c2mag,stats)
	if options.gain is None:
	    g = self.u.get_gain_range()
	    options.gain = float(g.start()+g.stop())/2			# if no gain was specified, use the mid-point in dB
示例#10
0
  def __init__(self, fft_length):
    gr.hier_block2.__init__(self, "timing_metric",
        gr.io_signature(1,1,gr.sizeof_gr_complex),
        gr.io_signature(1,1,gr.sizeof_float))

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

    # P(d)
    nominator = schmidl_nominator(fft_length)

    # R(d)
    denominator = schmidl_denominator(fft_length)

    # |P(d)| ** 2 / (R(d)) ** 2
    p_mag_sqrd = gr.complex_to_mag_squared()
    r_sqrd = gr.multiply_ff()
    self.timing_metric = gr.divide_ff()

    self.connect(self.input, nominator, p_mag_sqrd, (self.timing_metric,0))
    self.connect(self.input, denominator, (r_sqrd,0))
    self.connect(denominator, (r_sqrd,1))
    self.connect(r_sqrd, (self.timing_metric,1))
    self.connect(self.timing_metric, self)

    # calculate epsilon from P(d), epsilon is normalized fractional frequency offset
    #angle = gr.complex_to_arg()
    #self.epsilon = gr.multiply_const_ff(1.0/math.pi)
    #self.connect(nominator, angle, self.epsilon)

    try:
        gr.hier_block.update_var_names(self, "schmidl", vars())
        gr.hier_block.update_var_names(self, "schmidl", vars(self))
    except:
        pass
示例#11
0
def ms_to_file(hb,block,filename,N=4096,delay=0,fft=False,scale=1):
  streamsize = determine_streamsize(block)
  vlen = streamsize/gr.sizeof_gr_complex

  blks = [block]

  if fft and vlen > 1:
    gr_fft = fft_blocks.fft_vcc(vlen,True,[],True)
    blks.append(gr_fft)

  mag_sqrd = gr.complex_to_mag_squared(vlen)
  blks.append(mag_sqrd)

  if vlen > 1:
    v2s = blocks.vector_to_stream(gr.sizeof_float,vlen)
    blks.append(v2s)

  if delay != 0:
    delayline = delayline_ff(delay)
    blks.append(delayline)

  gr_scale = gr.multiply_const_ff(scale)
  blks.append(gr_scale)

  filter = gr.fir_filter_fff(1,[1.0/N]*N)
  blks.append(filter)

  for i in range(len(blks)-1):
    hb.connect(blks[i],blks[i+1])

  log_to_file(hb,filter,filename)
示例#12
0
  def __init__(self, fft_length, pn_weights):
    gr.hier_block2.__init__(self, "modified_timing_metric",
        gr.io_signature(1,1,gr.sizeof_gr_complex),
        gr.io_signature(1,1,gr.sizeof_float))

    assert(len(pn_weights) == fft_length)

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

    # P(d) = sum(0 to L-1, conj(delayed(r)) * r)
    conj = gr.conjugate_cc()
    mixer = gr.multiply_cc()
    nominator = gr.fir_filter_ccf(1,[pn_weights[fft_length-i-1]*pn_weights[fft_length/2-i-1] for i in range(fft_length/2)])

    self.connect(self.input, delay(gr.sizeof_gr_complex,fft_length/2), conj, (mixer,0))
    self.connect(self.input, (mixer,1))
    self.connect(mixer, nominator)
    # moving_avg = P(d)

    # R(d)
    denominator = schmidl_denominator(fft_length)

    # |P(d)| ** 2 / (R(d)) ** 2
    p_mag_sqrd = gr.complex_to_mag_squared()
    r_sqrd = gr.multiply_ff()
    self.timing_metric = gr.divide_ff()

    self.connect(nominator, p_mag_sqrd, (self.timing_metric,0))
    self.connect(self.input, denominator, (r_sqrd,0))
    self.connect(denominator, (r_sqrd,1))
    self.connect(r_sqrd, (self.timing_metric,1))
    self.connect(self.timing_metric, self)
示例#13
0
    def __init__(self, samp_rate=1600000, samp_per_sym=16, verbose=0, msgq=0, freq_error=-0.0025000):
        gr.hier_block2.__init__(
            self, "Wmbus Phy1", gr.io_signature(1, 1, gr.sizeof_gr_complex * 1), gr.io_signature(0, 0, 0)
        )

        ##################################################
        # Parameters
        ##################################################
        self.samp_rate = samp_rate
        self.samp_per_sym = samp_per_sym
        self.verbose = verbose
        self.msgq = msgq
        self.freq_error = freq_error

        ##################################################
        # Blocks
        ##################################################
        self.wmbus_demod_0 = wmbus_demod(samp_rate=1600000, samp_per_sym=16, freq_error=-0.0025000)
        self.gr_nlog10_ff_0 = gr.nlog10_ff(10, 1, 0)
        self.gr_complex_to_mag_squared_0 = gr.complex_to_mag_squared(1)
        self.fir_filter_xxx_0 = filter.fir_filter_fff(samp_per_sym, (16 * [1.0 / 16]))
        self.any_sink_0_1 = mbus.framer(msgq, verbose)
        self.any_0 = mbus.correlate_preamble()

        ##################################################
        # Connections
        ##################################################
        self.connect((self.any_0, 0), (self.any_sink_0_1, 0))
        self.connect((self.gr_complex_to_mag_squared_0, 0), (self.gr_nlog10_ff_0, 0))
        self.connect((self.gr_nlog10_ff_0, 0), (self.fir_filter_xxx_0, 0))
        self.connect((self.fir_filter_xxx_0, 0), (self.any_sink_0_1, 1))
        self.connect((self, 0), (self.gr_complex_to_mag_squared_0, 0))
        self.connect((self, 0), (self.wmbus_demod_0, 0))
        self.connect((self.wmbus_demod_0, 0), (self.any_0, 0))
示例#14
0
 def __init__(self, dpss, fftshift=False):
     gr.hier_block2.__init__(self, "eigenspectrum",
             gr.io_signature(1, 1, gr.sizeof_gr_complex*len(dpss)),
             gr.io_signature(1, 1, gr.sizeof_float*len(dpss)))
     self.window = dpss
     self.fft = gr.fft_vcc(len(dpss), True, self.window, fftshift)
     self.c2mag = gr.complex_to_mag_squared(len(dpss))
     self.connect(self, self.fft, self.c2mag, self)
示例#15
0
 def __init__(self, dpss, fftshift=False):
     gr.hier_block2.__init__(self, "eigenspectrum",
             gr.io_signature(1, 1, gr.sizeof_gr_complex*len(dpss)),
             gr.io_signature(1, 1, gr.sizeof_float*len(dpss)))
     self.window = dpss
     self.fft = gr.fft_vcc(len(dpss), True, self.window, fftshift)
     self.c2mag = gr.complex_to_mag_squared(len(dpss))
     self.connect(self, self.fft, self.c2mag, self)
示例#16
0
    def __init__(self, vlen):
        gr.hier_block2.__init__(
            self, "snr_estimator",
            gr.io_signature(2, 2, gr.sizeof_gr_complex * vlen),
            gr.io_signature(1, 1, gr.sizeof_float))

        reference = gr.kludge_copy(gr.sizeof_gr_complex * vlen)
        received = gr.kludge_copy(gr.sizeof_gr_complex * vlen)
        self.connect((self, 0), reference)
        self.connect((self, 1), received)

        received_conjugated = gr.conjugate_cc(vlen)
        self.connect(received, received_conjugated)

        R_innerproduct = gr.multiply_vcc(vlen)
        self.connect(reference, R_innerproduct)
        self.connect(received_conjugated, (R_innerproduct, 1))

        R_sum = vector_sum_vcc(vlen)
        self.connect(R_innerproduct, R_sum)

        R = gr.complex_to_mag_squared()
        self.connect(R_sum, R)

        received_magsqrd = gr.complex_to_mag_squared(vlen)
        reference_magsqrd = gr.complex_to_mag_squared(vlen)
        self.connect(received, received_magsqrd)
        self.connect(reference, reference_magsqrd)

        received_sum = vector_sum_vff(vlen)
        reference_sum = vector_sum_vff(vlen)
        self.connect(received_magsqrd, received_sum)
        self.connect(reference_magsqrd, reference_sum)

        P = gr.multiply_ff()
        self.connect(received_sum, (P, 0))
        self.connect(reference_sum, (P, 1))

        denominator = gr.sub_ff()
        self.connect(P, denominator)
        self.connect(R, (denominator, 1))

        rho_hat = gr.divide_ff()
        self.connect(R, rho_hat)
        self.connect(denominator, (rho_hat, 1))
        self.connect(rho_hat, self)
示例#17
0
    def __init__(self):
      sense_band_start=900*10**6
      sense_band_stop=940*10**6
      self.fft_size = options.fft_size
	self.ofdm_bins = options.sense_bins
# build graph
	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)
#log = gr.nlog10_ff(10, self.fft_size, -20*math.log10(self.fft_size)-10*math.log10(power/self.fft_size))

# modifications for USRP2
        print "*******************in sensor init********************"   
	if self.IS_USRP2:
	
	    self.u = usrp2.source_32fc(options.interface, options.MAC_addr)
	    self.u.set_decim(options.decim)
	    samp_rate = self.u.adc_rate() / self.u.decim()
	else:
	    self.u = gr.file_source(gr.sizeof_gr_complex,options.input_file, True)
	    samp_rate = 100e6 / options.decim

	self.freq_step =0.75* samp_rate
	#self.min_center_freq = (self.min_freq + self.max_freq)/2
	
	global BW
	BW = 0.75* samp_rate #self.max_freq - self.min_freq
	global size
	size=self.fft_size
	
	global ofdm_bins
	ofdm_bins = self.ofdm_bins
	
	global usr
	#global thrshold_inorder
	
	usr=samp_rate
	nsteps = 10 #math.ceil((self.max_freq - self.min_freq) / self.freq_step)
	self.max_center_freq = self.min_center_freq + (nsteps * self.freq_step)
	self.next_freq = self.min_center_freq
	tune_delay = max(0, int(round(options.tune_delay * samp_rate / self.fft_size))) # in fft_frames
	print tune_delay
	dwell_delay = max(1, int(round(options.dwell_delay * samp_rate / self.fft_size))) # in fft_frames
	print dwell_delay
	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)
	self.connect(self.u, s2v, fft,c2mag,stats)
	if options.gain is None:
# if no gain was specified, use the mid-point in dB
	    g = self.u.gain_range()
	    options.gain = float(g[0]+g[1])/2
示例#18
0
  def __init__(self,vlen):
    gr.hier_block2.__init__(self,"snr_estimator",
      gr.io_signature(2,2,gr.sizeof_gr_complex*vlen),
      gr.io_signature(1,1,gr.sizeof_float))

    reference = gr.kludge_copy(gr.sizeof_gr_complex*vlen)
    received = gr.kludge_copy(gr.sizeof_gr_complex*vlen)
    self.connect((self,0),reference)
    self.connect((self,1),received)

    received_conjugated = gr.conjugate_cc(vlen)
    self.connect(received,received_conjugated)

    R_innerproduct = gr.multiply_vcc(vlen)
    self.connect(reference,R_innerproduct)
    self.connect(received_conjugated,(R_innerproduct,1))

    R_sum = vector_sum_vcc(vlen)
    self.connect(R_innerproduct,R_sum)

    R = gr.complex_to_mag_squared()
    self.connect(R_sum,R)

    received_magsqrd = gr.complex_to_mag_squared(vlen)
    reference_magsqrd = gr.complex_to_mag_squared(vlen)
    self.connect(received,received_magsqrd)
    self.connect(reference,reference_magsqrd)

    received_sum = vector_sum_vff(vlen)
    reference_sum = vector_sum_vff(vlen)
    self.connect(received_magsqrd,received_sum)
    self.connect(reference_magsqrd,reference_sum)

    P = gr.multiply_ff()
    self.connect(received_sum,(P,0))
    self.connect(reference_sum,(P,1))

    denominator = gr.sub_ff()
    self.connect(P,denominator)
    self.connect(R,(denominator,1))

    rho_hat = gr.divide_ff()
    self.connect(R,rho_hat)
    self.connect(denominator,(rho_hat,1))
    self.connect(rho_hat,self)
示例#19
0
    def __init__(self):
        gr.hier_block2.__init__(self, "symbol_0_slicer",
                                gr.io_signature(2, 2, gr.sizeof_gr_complex),
                                gr.io_signature(1, 1, gr.sizeof_float))
        adder = gr.add_cc()
        to_mag = gr.complex_to_mag_squared()

        self.connect((self, 0), (adder, 0))
        self.connect((self, 1), (adder, 1))
        self.connect(adder, to_mag, self)
示例#20
0
    def __init__(self):
        gr.hier_block2.__init__(self, "symbol_1_slicer",
                                gr.io_signature(2, 2, gr.sizeof_gr_complex),
                                gr.io_signature(1, 1, gr.sizeof_float))
        diff = gr.sub_cc()
        to_mag = gr.complex_to_mag_squared()

        self.connect((self, 0), (diff, 0))
        self.connect((self, 1), (diff, 1))
        self.connect(diff, to_mag, self)
示例#21
0
    def __init__(self,
                 N_id_2,
                 decim=16,
                 avg_halfframes=2 * 8,
                 freq_corr=0,
                 dump=None):
        gr.hier_block2.__init__(
            self,
            "PSS correlator",
            gr.io_signature(1, 1, gr.sizeof_gr_complex),
            gr.io_signature(1, 1, gr.sizeof_float),
        )
        vec_half_frame = 30720 * 5 / decim

        self.taps = []
        for i in range(0, 3):
            self.taps.append(
                gen_pss_td(i, N_re=2048 / decim,
                           freq_corr=freq_corr).get_data_conj_rev())
        self.corr = filter.fir_filter_ccc(1, self.taps[N_id_2])
        self.mag = gr.complex_to_mag_squared()
        self.vec = gr.stream_to_vector(gr.sizeof_float * 1, vec_half_frame)
        self.deint = gr.deinterleave(gr.sizeof_float * vec_half_frame)
        self.add = gr.add_vff(vec_half_frame)
        self.argmax = gr.argmax_fs(vec_half_frame)
        self.null = gr.null_sink(gr.sizeof_short * 1)
        self.max = gr.max_ff(vec_half_frame)
        self.to_float = gr.short_to_float(1, 1. / decim)
        self.interleave = gr.interleave(gr.sizeof_float)
        #self.framestart = gr.add_const_ii(-160-144*5-2048*6+30720*5)

        self.connect(self, self.corr, self.mag, self.vec)
        self.connect((self.argmax, 1), self.null)
        #self.connect(self.argmax, self.to_float, self.to_int, self.framestart, self)
        self.connect(self.argmax, self.to_float, self.interleave, self)
        self.connect(self.max, (self.interleave, 1))

        if avg_halfframes == 1:
            self.connect(self.vec, self.argmax)
            self.connect(self.vec, self.max)
        else:
            self.connect(self.vec, self.deint)
            self.connect(self.add, self.argmax)
            self.connect(self.add, self.max)
            for i in range(0, avg_halfframes):
                self.connect((self.deint, i), (self.add, i))

        if dump != None:
            self.connect(
                self.mag,
                gr.file_sink(gr.sizeof_float, dump + "_pss_corr_f.cfile"))
            self.connect(
                self.add,
                gr.file_sink(gr.sizeof_float * vec_half_frame,
                             dump + "_pss_corr_add_f.cfile"))
示例#22
0
 def __init__ ( self, fft_length ):
   gr.hier_block2.__init__(self, "recursive_timing_metric",
       gr.io_signature(1,1,gr.sizeof_gr_complex),
       gr.io_signature(1,1,gr.sizeof_float))
   
   self.input = gr.kludge_copy(gr.sizeof_gr_complex)
   self.connect(self, self.input)
   
   # P(d) = sum(0 to L-1, conj(delayed(r)) * r)
   conj = gr.conjugate_cc()
   mixer = gr.multiply_cc()
   mix_delay = delay(gr.sizeof_gr_complex,fft_length/2+1)
   mix_diff = gr.sub_cc()
   nominator = accumulator_cc()
   inpdelay = delay(gr.sizeof_gr_complex,fft_length/2)
   
   self.connect(self.input, inpdelay, 
                conj, (mixer,0))
   self.connect(self.input, (mixer,1))
   self.connect(mixer,(mix_diff,0))
   self.connect(mixer, mix_delay, (mix_diff,1))
   self.connect(mix_diff,nominator)
   
   rmagsqrd = gr.complex_to_mag_squared()
   rm_delay = delay(gr.sizeof_float,fft_length+1)
   rm_diff = gr.sub_ff()
   denom = accumulator_ff()
   self.connect(self.input,rmagsqrd,rm_diff,gr.multiply_const_ff(0.5),denom)
   self.connect(rmagsqrd,rm_delay,(rm_diff,1))
   
   
   ps = gr.complex_to_mag_squared()
   rs = gr.multiply_ff()
   self.connect(nominator,ps)
   self.connect(denom,rs)
   self.connect(denom,(rs,1))
   
   div = gr.divide_ff()
   self.connect(ps,div)
   self.connect(rs,(div,1))
   
   self.connect(div,self)
示例#23
0
 def test_complex_to_mag_squared(self):
     src_data = (0, 1, -1, 3 + 4j, -3 - 4j, -3 + 4j)
     expected_result = (0, 1, 1, 25, 25, 25)
     src = gr.vector_source_c(src_data)
     op = gr.complex_to_mag_squared()
     dst = gr.vector_sink_f()
     self.tb.connect(src, op)
     self.tb.connect(op, dst)
     self.tb.run()
     actual_result = dst.data()
     self.assertFloatTuplesAlmostEqual(expected_result, actual_result, 5)
示例#24
0
 def test_complex_to_mag_squared (self):
     src_data = (0, 1, -1, 3+4j, -3-4j, -3+4j)
     expected_result = (0, 1, 1, 25, 25, 25)
     src = gr.vector_source_c (src_data)
     op = gr.complex_to_mag_squared ()
     dst = gr.vector_sink_f ()
     self.tb.connect (src, op)
     self.tb.connect (op, dst)
     self.tb.run ()
     actual_result = dst.data ()
     self.assertFloatTuplesAlmostEqual (expected_result, actual_result,5)
示例#25
0
    def __init__(self, fft_length):
        gr.hier_block2.__init__(self, "recursive_timing_metric",
                                gr.io_signature(1, 1, gr.sizeof_gr_complex),
                                gr.io_signature(1, 1, gr.sizeof_float))

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

        # P(d) = sum(0 to L-1, conj(delayed(r)) * r)
        conj = gr.conjugate_cc()
        mixer = gr.multiply_cc()
        mix_delay = delay(gr.sizeof_gr_complex, fft_length / 2 + 1)
        mix_diff = gr.sub_cc()
        nominator = accumulator_cc()
        inpdelay = delay(gr.sizeof_gr_complex, fft_length / 2)

        self.connect(self.input, inpdelay, conj, (mixer, 0))
        self.connect(self.input, (mixer, 1))
        self.connect(mixer, (mix_diff, 0))
        self.connect(mixer, mix_delay, (mix_diff, 1))
        self.connect(mix_diff, nominator)

        rmagsqrd = gr.complex_to_mag_squared()
        rm_delay = delay(gr.sizeof_float, fft_length + 1)
        rm_diff = gr.sub_ff()
        denom = accumulator_ff()
        self.connect(self.input, rmagsqrd, rm_diff, gr.multiply_const_ff(0.5),
                     denom)
        self.connect(rmagsqrd, rm_delay, (rm_diff, 1))

        ps = gr.complex_to_mag_squared()
        rs = gr.multiply_ff()
        self.connect(nominator, ps)
        self.connect(denom, rs)
        self.connect(denom, (rs, 1))

        div = gr.divide_ff()
        self.connect(ps, div)
        self.connect(rs, (div, 1))

        self.connect(div, self)
示例#26
0
  def __init__(self, data_tones, num_symbols, mode=0):
    symbol_size = data_tones * gr.sizeof_gr_complex
    gr.hier_block2.__init__(self, "SNR",
      gr.io_signature2(2,2, symbol_size, symbol_size),
      gr.io_signature(1,1, gr.sizeof_float))

    sub = gr.sub_cc(data_tones)
    self.connect((self,0), (sub,0))
    self.connect((self,1), (sub,1))

    err = gr.complex_to_mag_squared(data_tones);
    self.connect(sub, err);
    pow = gr.complex_to_mag_squared(data_tones);
    self.connect((self,1), pow);

    if mode == 0:
      # one snr per symbol (num_symbols is ignored)
      snr = gr.divide_ff()
      self.connect(pow, gr.vector_to_stream(gr.sizeof_float, data_tones),
        gr.integrate_ff(data_tones), (snr,0))
      self.connect(err, gr.vector_to_stream(gr.sizeof_float, data_tones),
        gr.integrate_ff(data_tones), (snr,1))
      out = snr
    elif mode == 1:
      # one snr per packet
      snr = gr.divide_ff()
      self.connect(pow, gr.vector_to_stream(gr.sizeof_float, data_tones),
        gr.integrate_ff(data_tones*num_symbols), (snr,0))
      self.connect(err, gr.vector_to_stream(gr.sizeof_float, data_tones),
        gr.integrate_ff(data_tones*num_symbols), (snr,1))
      out = snr
    elif mode == 2:
      # one snr per frequency bin
      snr = gr.divide_ff(data_tones)
      self.connect(pow, raw.symbol_avg(data_tones, num_symbols), (snr,0))
      self.connect(err, raw.symbol_avg(data_tones, num_symbols), (snr,1))
      out = gr.vector_to_stream(gr.sizeof_float, data_tones)
      self.connect(snr, out)

    self.connect(out, gr.nlog10_ff(10), self)
示例#27
0
    def __init__(self):
        gr.hier_block2.__init__(self,
                                "symbol_1_slicer",
                                gr.io_signature(2, 2, gr.sizeof_gr_complex),
                                gr.io_signature(1, 1, gr.sizeof_float))
        diff = gr.sub_cc()
        to_mag = gr.complex_to_mag_squared()

        self.connect((self, 0), (diff, 0))
        self.connect((self, 1), (diff, 1))
        self.connect(diff, 
                     to_mag, 
                     self)
示例#28
0
    def __init__(self):
        gr.hier_block2.__init__(self,
                                "symbol_0_slicer",
                                gr.io_signature(2, 2, gr.sizeof_gr_complex),
                                gr.io_signature(1, 1, gr.sizeof_float))
        adder = gr.add_cc()
        to_mag = gr.complex_to_mag_squared()

        self.connect((self, 0), (adder, 0))
        self.connect((self, 1), (adder, 1))
        self.connect(adder,
                     to_mag,
                     self)
示例#29
0
    def __init__(self,
                 sample_rate,
                 fft_size,
                 ref_scale,
                 frame_rate,
                 avg_alpha,
                 average,
                 win=None):
        """
        Create an log10(abs(fft)) stream chain.
        Provide access to the setting the filter and sample rate.
        @param sample_rate        Incoming stream sample rate
        @param fft_size                Number of FFT bins
        @param ref_scale        Sets 0 dB value input amplitude
        @param frame_rate        Output frame rate
        @param avg_alpha        FFT averaging (over time) constant [0.0-1.0]
        @param average                Whether to average [True, False]
        @param win              the window taps generation function
        """
        gr.hier_block2.__init__(
            self,
            self._name,
            gr.io_signature(1, 1, self._item_size),  # Input signature
            gr.io_signature(1, 1,
                            gr.sizeof_float * fft_size))  # Output signature

        self._sd = stream_to_vector_decimator(item_size=self._item_size,
                                              sample_rate=sample_rate,
                                              vec_rate=frame_rate,
                                              vec_len=fft_size)

        if win is None: win = window.blackmanharris
        fft_window = win(fft_size)
        fft = self._fft_block[0](fft_size, True, fft_window)
        window_power = sum(map(lambda x: x * x, fft_window))

        c2magsq = gr.complex_to_mag_squared(fft_size)
        self._avg = gr.single_pole_iir_filter_ff(1.0, fft_size)
        self._log = gr.nlog10_ff(
            10,
            fft_size,
            -20 * math.log10(fft_size)  # Adjust for number of bins
            - 10 *
            math.log10(window_power / fft_size)  # Adjust for windowing loss
            - 20 * math.log10(ref_scale / 2))  # Adjust for reference scale
        self.connect(self, self._sd, fft, c2magsq, self._avg, self._log, self)

        self._average = average
        self._avg_alpha = avg_alpha
        self.set_avg_alpha(avg_alpha)
        self.set_average(average)
  def __init__( self, vlen, startup ):
    gr.hier_block2.__init__( self,
          "vector_acc_se",
          gr.io_signature( 1, 1, gr.sizeof_gr_complex * vlen ),
          gr.io_signature( 1, 1, gr.sizeof_float ) )

    squared_error_subc = gr.complex_to_mag_squared( vlen )
    squared_error_block = ofdm.vector_sum_vff( vlen )
    accumulated_squared_error = ofdm.accumulator_ff()

    if startup > 0:
      startup_skip = gr.skiphead( gr.sizeof_gr_complex * vlen, startup )
      self.connect( self, startup_skip, squared_error_subc, squared_error_block,
                    accumulated_squared_error, self )
    else:
      self.connect( self, squared_error_subc, squared_error_block,
                    accumulated_squared_error, self )
示例#31
0
    def __init__(self, fft_length):
        gr.hier_block2.__init__(self, "schmidl_denominator",
                                gr.io_signature(1, 1, gr.sizeof_gr_complex),
                                gr.io_signature(1, 1, gr.sizeof_float))

        # R(d) = sum(0 to L-1, |r_d|**2)
        r_mag_sqrd = gr.complex_to_mag_squared()
        r_mov_avg = gr.fir_filter_fff(1, [0.5 for i in range(fft_length)])
        #r_mov_avg_half = gr.multiply_const_ff(0.5)
        #r_mov_avg = moving_sum_cc(fft_length)

        self.connect(self, r_mag_sqrd, r_mov_avg, self)
        # r_mov_avg = R(d)

        try:
            gr.hier_block.update_var_names(self, "schmidl_denom", vars())
            gr.hier_block.update_var_names(self, "schmidl_denom", vars(self))
        except:
            pass
示例#32
0
  def __init__(self, fft_length):
    gr.hier_block2.__init__(self, "schmidl_denominator",
        gr.io_signature(1,1,gr.sizeof_gr_complex),
        gr.io_signature(1,1,gr.sizeof_float))

    # R(d) = sum(0 to L-1, |r_d|**2)
    r_mag_sqrd = gr.complex_to_mag_squared()
    r_mov_avg = gr.fir_filter_fff(1,[0.5 for i in range(fft_length)])
    #r_mov_avg_half = gr.multiply_const_ff(0.5)
    #r_mov_avg = moving_sum_cc(fft_length)

    self.connect(self, r_mag_sqrd, r_mov_avg, self)
    # r_mov_avg = R(d)

    try:
        gr.hier_block.update_var_names(self, "schmidl_denom", vars())
        gr.hier_block.update_var_names(self, "schmidl_denom", vars(self))
    except:
        pass
示例#33
0
  def __init__(self, N_id_2, decim=16, avg_halfframes=2*8, freq_corr=0, dump=None):
    gr.hier_block2.__init__(
        self, "PSS correlator",
        gr.io_signature(1, 1, gr.sizeof_gr_complex),
        gr.io_signature(1, 1, gr.sizeof_float),
    )
    vec_half_frame = 30720*5/decim
    
    self.taps = []
    for i in range(0,3):
      self.taps.append(gen_pss_td(i, N_re=2048/decim, freq_corr=freq_corr).get_data_conj_rev())
    self.corr = filter.fir_filter_ccc(1, self.taps[N_id_2])
    self.mag = gr.complex_to_mag_squared()
    self.vec = gr.stream_to_vector(gr.sizeof_float*1, vec_half_frame)
    self.deint = gr.deinterleave(gr.sizeof_float*vec_half_frame)
    self.add = gr.add_vff(vec_half_frame)
    self.argmax = gr.argmax_fs(vec_half_frame)
    self.null = gr.null_sink(gr.sizeof_short*1)
    self.max = gr.max_ff(vec_half_frame)
    self.to_float = gr.short_to_float(1, 1./decim)
    self.interleave = gr.interleave(gr.sizeof_float)
    #self.framestart = gr.add_const_ii(-160-144*5-2048*6+30720*5)
    
    self.connect(self, self.corr, self.mag, self.vec)
    self.connect((self.argmax,1), self.null)
    #self.connect(self.argmax, self.to_float, self.to_int, self.framestart, self)
    self.connect(self.argmax, self.to_float, self.interleave, self)
    self.connect(self.max, (self.interleave,1))
    
    if avg_halfframes == 1:
      self.connect(self.vec, self.argmax)
      self.connect(self.vec, self.max)
    else:
      self.connect(self.vec, self.deint)
      self.connect(self.add, self.argmax)
      self.connect(self.add, self.max)
      for i in range(0, avg_halfframes):
        self.connect((self.deint, i), (self.add, i))

    if dump != None:
      self.connect(self.mag, gr.file_sink(gr.sizeof_float, dump + "_pss_corr_f.cfile"))
      self.connect(self.add, gr.file_sink(gr.sizeof_float*vec_half_frame, dump + "_pss_corr_add_f.cfile"))
    def __init__(self, fs, fd, svn, alpha, dump_bins=False):
        fft_size = int( 1e-3*fs)

        gr.hier_block2.__init__(self,
            "single_channel_correlator",
            gr.io_signature(1,1, gr.sizeof_gr_complex*fft_size),
            gr.io_signature(1,1, gr.sizeof_float*fft_size))

        lc = local_code(svn=svn, fs=fs, fd=fd)
        mult = gr.multiply_vcc(fft_size)
        ifft = gr.fft_vcc(fft_size, False, [])
        mag = gr.complex_to_mag_squared(fft_size)
        self.iir = gr.single_pole_iir_filter_ff( alpha, fft_size)

        self.connect( self, (mult, 0))
        self.connect( lc,   (mult, 1))
        self.connect( mult, ifft, mag, self.iir, self)

        if dump_bins == True:
            self.connect_debug_sink(self.iir,fft_size,'/home/trondd/opengnss_output', fd)
    def __init__(self, fs, fd, svn, alpha, dump_bins=False):
        fft_size = int(1e-3 * fs)

        gr.hier_block2.__init__(
            self, "single_channel_correlator",
            gr.io_signature(1, 1, gr.sizeof_gr_complex * fft_size),
            gr.io_signature(1, 1, gr.sizeof_float * fft_size))

        lc = local_code(svn=svn, fs=fs, fd=fd)
        mult = gr.multiply_vcc(fft_size)
        ifft = gr.fft_vcc(fft_size, False, [])
        mag = gr.complex_to_mag_squared(fft_size)
        self.iir = gr.single_pole_iir_filter_ff(alpha, fft_size)

        self.connect(self, (mult, 0))
        self.connect(lc, (mult, 1))
        self.connect(mult, ifft, mag, self.iir, self)

        if dump_bins == True:
            self.connect_debug_sink(self.iir, fft_size,
                                    '/home/trondd/opengnss_output', fd)
示例#36
0
	def __init__(self, samp_rate=1600000, samp_per_sym=16, verbose=0, msgq=0, freq_error=-0.0025000):
		gr.hier_block2.__init__(
			self, "Wmbus Phy1",
			gr.io_signature(1, 1, gr.sizeof_gr_complex*1),
			gr.io_signature(0, 0, 0),
		)

		##################################################
		# Parameters
		##################################################
		self.samp_rate = samp_rate
		self.samp_per_sym = samp_per_sym
		self.verbose = verbose
		self.msgq = msgq
		self.freq_error = freq_error

		##################################################
		# Blocks
		##################################################
		self.wmbus_demod_0 = wmbus_demod(
			samp_rate=1600000,
			samp_per_sym=16,
			freq_error=-0.0025000,
		)
		self.gr_nlog10_ff_0 = gr.nlog10_ff(10, 1, 0)
		self.gr_complex_to_mag_squared_0 = gr.complex_to_mag_squared(1)
		self.fir_filter_xxx_0 = filter.fir_filter_fff(samp_per_sym, (16*[1./16]))
		self.any_sink_0_1 = mbus.framer(msgq, verbose) 
		self.any_0 = mbus.correlate_preamble()

		##################################################
		# Connections
		##################################################
		self.connect((self.any_0, 0), (self.any_sink_0_1, 0))
		self.connect((self.gr_complex_to_mag_squared_0, 0), (self.gr_nlog10_ff_0, 0))
		self.connect((self.gr_nlog10_ff_0, 0), (self.fir_filter_xxx_0, 0))
		self.connect((self.fir_filter_xxx_0, 0), (self.any_sink_0_1, 1))
		self.connect((self, 0), (self.gr_complex_to_mag_squared_0, 0))
		self.connect((self, 0), (self.wmbus_demod_0, 0))
		self.connect((self.wmbus_demod_0, 0), (self.any_0, 0))
示例#37
0
    def __init__(self, sample_rate, fft_size, ref_scale, frame_rate, avg_alpha, average, win=None):
        """
        Create an log10(abs(fft)) stream chain.
        Provide access to the setting the filter and sample rate.
        
        Args:
            sample_rate: Incoming stream sample rate
            fft_size: Number of FFT bins
            ref_scale: Sets 0 dB value input amplitude
            frame_rate: Output frame rate
            avg_alpha: FFT averaging (over time) constant [0.0-1.0]
            average: Whether to average [True, False]
            win: the window taps generation function
        """
        gr.hier_block2.__init__(self, self._name,
                                gr.io_signature(1, 1, self._item_size),          # Input signature
                                gr.io_signature(1, 1, gr.sizeof_float*fft_size)) # Output signature

        self._sd = stream_to_vector_decimator(item_size=self._item_size,
                                              sample_rate=sample_rate,
                                              vec_rate=frame_rate,
                                              vec_len=fft_size)

        if win is None: win = window.blackmanharris
        fft_window = win(fft_size)
        fft = self._fft_block[0](fft_size, True, fft_window)
        window_power = sum(map(lambda x: x*x, fft_window))

        c2magsq = gr.complex_to_mag_squared(fft_size)
        self._avg = filter.single_pole_iir_filter_ff(1.0, fft_size)
        self._log = gr.nlog10_ff(10, fft_size,
                                 -20*math.log10(fft_size)              # Adjust for number of bins
                                 -10*math.log10(window_power/fft_size) # Adjust for windowing loss
                                 -20*math.log10(ref_scale/2))      # Adjust for reference scale
        self.connect(self, self._sd, fft, c2magsq, self._avg, self._log, self)

        self._average = average
        self._avg_alpha = avg_alpha
        self.set_avg_alpha(avg_alpha)
        self.set_average(average)
示例#38
0
    def __init__(self, fft_length, pn_weights):
        gr.hier_block2.__init__(self, "modified_timing_metric",
                                gr.io_signature(1, 1, gr.sizeof_gr_complex),
                                gr.io_signature(1, 1, gr.sizeof_float))

        assert (len(pn_weights) == fft_length)

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

        # P(d) = sum(0 to L-1, conj(delayed(r)) * r)
        conj = gr.conjugate_cc()
        mixer = gr.multiply_cc()
        nominator = gr.fir_filter_ccf(1, [
            pn_weights[fft_length - i - 1] * pn_weights[fft_length / 2 - i - 1]
            for i in range(fft_length / 2)
        ])

        self.connect(self.input, delay(gr.sizeof_gr_complex, fft_length / 2),
                     conj, (mixer, 0))
        self.connect(self.input, (mixer, 1))
        self.connect(mixer, nominator)
        # moving_avg = P(d)

        # R(d)
        denominator = schmidl_denominator(fft_length)

        # |P(d)| ** 2 / (R(d)) ** 2
        p_mag_sqrd = gr.complex_to_mag_squared()
        r_sqrd = gr.multiply_ff()
        self.timing_metric = gr.divide_ff()

        self.connect(nominator, p_mag_sqrd, (self.timing_metric, 0))
        self.connect(self.input, denominator, (r_sqrd, 0))
        self.connect(denominator, (r_sqrd, 1))
        self.connect(r_sqrd, (self.timing_metric, 1))
        self.connect(self.timing_metric, self)
示例#39
0
    def __init__(self, fft_length):
        gr.hier_block2.__init__(self, "timing_metric",
                                gr.io_signature(1, 1, gr.sizeof_gr_complex),
                                gr.io_signature(1, 1, gr.sizeof_float))

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

        # P(d)
        nominator = schmidl_nominator(fft_length)

        # R(d)
        denominator = schmidl_denominator(fft_length)

        # |P(d)| ** 2 / (R(d)) ** 2
        p_mag_sqrd = gr.complex_to_mag_squared()
        r_sqrd = gr.multiply_ff()
        self.timing_metric = gr.divide_ff()

        self.connect(self.input, nominator, p_mag_sqrd,
                     (self.timing_metric, 0))
        self.connect(self.input, denominator, (r_sqrd, 0))
        self.connect(denominator, (r_sqrd, 1))
        self.connect(r_sqrd, (self.timing_metric, 1))
        self.connect(self.timing_metric, self)

        # calculate epsilon from P(d), epsilon is normalized fractional frequency offset
        #angle = gr.complex_to_arg()
        #self.epsilon = gr.multiply_const_ff(1.0/math.pi)
        #self.connect(nominator, angle, self.epsilon)

        try:
            gr.hier_block.update_var_names(self, "schmidl", vars())
            gr.hier_block.update_var_names(self, "schmidl", vars(self))
        except:
            pass
示例#40
0
    def __init__(self, length, debug=False):
        """
        Hierarchical block to detect Null symbols

        @param length length of the Null symbol (in samples)
        @param debug whether to write signals out to files
        """
        gr.hier_block2.__init__(
            self,
            "detect_null",
            gr.io_signature(1, 1, gr.sizeof_gr_complex),  # input signature
            gr.io_signature(1, 1, gr.sizeof_char))  # output signature

        # get the magnitude squared
        self.ns_c2magsquared = gr.complex_to_mag_squared()
        self.ns_moving_sum = dabp.moving_sum_ff(length)
        self.ns_invert = gr.multiply_const_ff(-1)

        # peak detector on the inverted, summed up signal -> we get the nulls (i.e. the position of the start of a frame)
        self.ns_peak_detect = gr.peak_detector_fb(
            0.6, 0.7, 10, 0.0001
        )  # mostly found by try and error -> remember that the values are negative!

        # connect it all
        self.connect(self, self.ns_c2magsquared, self.ns_moving_sum,
                     self.ns_invert, self.ns_peak_detect, self)

        if debug:
            self.connect(
                self.ns_invert,
                gr.file_sink(gr.sizeof_float,
                             "debug/ofdm_sync_dabp_ns_filter_inv_f.dat"))
            self.connect(
                self.ns_peak_detect,
                gr.file_sink(gr.sizeof_char,
                             "debug/ofdm_sync_dabp_peak_detect_b.dat"))
示例#41
0
    def __init__(self, subc, vlen, ss):
        gr.hier_block2.__init__(
            self,
            "new_snr_estimator",
            gr.io_signature(2, 2, gr.sizeof_gr_complex * vlen),
            #gr.io_signature2(2,2,gr.sizeof_float*vlen,gr.sizeof_float*vlen/ss*(ss-1)))
            gr.io_signature2(2, 2, gr.sizeof_float * vlen, gr.sizeof_float))

        print "Created Milan's SINR estimator"

        trigger = [0] * vlen
        trigger[0] = 1

        v = range(vlen / ss)
        ones_ind = map(lambda z: z * ss, v)

        skip2_pr0 = skip(gr.sizeof_gr_complex, vlen)
        skip2_pr1 = skip(gr.sizeof_gr_complex, vlen)
        for x in ones_ind:
            skip2_pr0.skip(x)
            skip2_pr1.skip(x)

        #print "skipped ones",ones_ind

        v2s_pr0 = gr.vector_to_stream(gr.sizeof_gr_complex, vlen)
        v2s_pr1 = gr.vector_to_stream(gr.sizeof_gr_complex, vlen)

        s2v2_pr0 = gr.stream_to_vector(gr.sizeof_gr_complex,
                                       vlen / ss * (ss - 1))
        trigger_src_2_pr0 = gr.vector_source_b(trigger, True)
        s2v2_pr1 = gr.stream_to_vector(gr.sizeof_gr_complex,
                                       vlen / ss * (ss - 1))
        trigger_src_2_pr1 = gr.vector_source_b(trigger, True)

        mag_sq_zeros_pr0 = gr.complex_to_mag_squared(vlen / ss * (ss - 1))
        mag_sq_zeros_pr1 = gr.complex_to_mag_squared(vlen / ss * (ss - 1))

        filt_zeros_pr0 = gr.single_pole_iir_filter_ff(0.01,
                                                      vlen / ss * (ss - 1))
        filt_zeros_pr1 = gr.single_pole_iir_filter_ff(0.01,
                                                      vlen / ss * (ss - 1))
        v1 = vlen / ss * (ss - 1)
        vevc1 = [-1] * v1
        neg_nomin_z = gr.multiply_const_vff(vevc1)
        div_z = gr.divide_ff(vlen / ss * (ss - 1))
        on_zeros = gr.add_const_vff(vevc1)
        sum_zeros = add_vff(vlen / ss * (ss - 1))

        # For average
        sum_all = vector_sum_vff(vlen)
        mult = gr.multiply_const_ff(1. / vlen)
        scsnr_db_av = gr.nlog10_ff(10, 1, 0)
        filt_end_av = gr.single_pole_iir_filter_ff(0.1)

        self.connect((self, 0), v2s_pr0, skip2_pr0, s2v2_pr0, mag_sq_zeros_pr0,
                     filt_zeros_pr0)
        self.connect(trigger_src_2_pr0, (skip2_pr0, 1))

        self.connect((self, 1), v2s_pr1, skip2_pr1, s2v2_pr1, mag_sq_zeros_pr1,
                     filt_zeros_pr1)
        self.connect(trigger_src_2_pr1, (skip2_pr1, 1))

        # On zeros
        self.connect(filt_zeros_pr1, (sum_zeros, 0))
        self.connect(filt_zeros_pr0, neg_nomin_z, (sum_zeros, 1))
        self.connect(sum_zeros, div_z)
        self.connect(filt_zeros_pr0, (div_z, 1))

        scsnr_db = gr.nlog10_ff(10, vlen, 0)
        filt_end = gr.single_pole_iir_filter_ff(0.1, vlen)

        dd = []
        for i in range(vlen / ss):
            dd.extend([i * ss])
        #print dd
        interpolator = sinr_interpolator(vlen, ss, dd)

        self.connect(div_z, interpolator, filt_end, scsnr_db, self)
        self.connect(interpolator, sum_all, mult, scsnr_db_av, filt_end_av,
                     (self, 1))
示例#42
0
  def __init__(self, vlen):
    gr.hier_block2.__init__(self, "snr_estimator",
        gr.io_signature2(2,2,gr.sizeof_gr_complex,gr.sizeof_char),
        gr.io_signature (1,1,gr.sizeof_float))
    
    data_in = (self,0)
    trig_in = (self,1)
    snr_out = (self,0)

    ## Preamble Extraction
    sampler = vector_sampler(gr.sizeof_gr_complex,vlen)
    self.connect(data_in,sampler)
    self.connect(trig_in,(sampler,1))
    
    ## Algorithm implementation
    estim = sc_snr_estimator(vlen)
    self.connect(sampler,estim)
    self.connect(estim,snr_out)
    
    return 
  
  
  

    ## Split block into two parts
    splitter = gr.vector_to_streams(gr.sizeof_gr_complex*vlen/2,2)
    self.connect(sampler,splitter)

    ## Conjugate first half block
    conj = gr.conjugate_cc(vlen/2)
    self.connect(splitter,conj)

    ## Vector multiplication of both half blocks
    vmult = gr.multiply_vcc(vlen/2)
    self.connect(conj,vmult)
    self.connect((splitter,1),(vmult,1))

    ## Sum of Products
    psum = vector_sum_vcc(vlen/2)
    self.connect(vmult,psum)

    ## Magnitude of P(d)
    p_mag = gr.complex_to_mag()
    self.connect(psum,p_mag)

    ## Squared Magnitude of block
    r_magsqrd = gr.complex_to_mag_squared(vlen)
    self.connect(sampler,r_magsqrd)

    ## Sum of squared second half block
    r_sum = vector_sum_vff(vlen)
    self.connect(r_magsqrd,r_sum)

    ## Square Root of Metric
    m_sqrt = gr.divide_ff()
    self.connect(p_mag,(m_sqrt,0))
    self.connect(r_sum,gr.multiply_const_ff(0.5),(m_sqrt,1))

    ## Denominator of SNR estimate
    denom = gr.add_const_ff(1)
    neg_m_sqrt = gr.multiply_const_ff(-1.0)
    self.connect(m_sqrt,limit_vff(1,1-2e-5,-1000),neg_m_sqrt,denom)

    ## SNR estimate
    snr_est = gr.divide_ff()
    self.connect(m_sqrt,(snr_est,0))
    self.connect(denom,(snr_est,1))

    ## Setup Output Connections
    self.connect(snr_est,self)
示例#43
0
    def __init__(self, tuner_callback, options):
        gr.hier_block2.__init__(
            self,
            "sense_path",
            gr.io_signature(1, 1, gr.sizeof_gr_complex),  # Input signature
            gr.io_signature(0, 0, 0))  # Output signature

        self.usrp_rate = options.channel_rate
        self.usrp_tune = tuner_callback

        self.threshold = options.threshold

        #self.freq_step = options.chan_bandwidth
        #self.min_freq = options.start_freq
        #self.max_freq = options.end_freq
        self.hold_freq = False

        self.channels = [
            600000000, 620000000, 625000000, 640000000, 645000000, 650000000
        ]
        self.current_chan = 0
        self.num_channels = len(
            self.channels)  #(self.max_freq - self.min_freq)/self.freq_step

        #if self.min_freq > self.max_freq:
        #    self.min_freq, self.max_freq = self.max_freq, self.min_freq   # swap them

        self.fft_size = options.sense_fft_size

        if not options.real_time:
            realtime = False
        else:
            # Attempt to enable realtime scheduling
            r = gr.enable_realtime_scheduling()
            if r == gr.RT_OK:
                realtime = True
            else:
                realtime = False
                print "Note: failed to enable realtime scheduling"

        # build graph
        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.

        #changed on 2011 May 31, MR -- maybe change back at some point

        #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.next_freq = self.channels[
            self.current_chan]  #self.min_center_freq

        tune_delay = max(0,
                         int(
                             round(options.tune_delay * self.usrp_rate /
                                   self.fft_size)))  # in fft_frames
        dwell_delay = max(1,
                          int(
                              round(options.dwell_delay * self.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
        self.stats = gr.bin_statistics_f(self.fft_size, self.msgq,
                                         self._tune_callback, tune_delay,
                                         dwell_delay)

        # FIXME leave out the log10 until we speed it up
        #self.connect(self, s2v, fft, c2mag, log, stats)
        self.connect(self, s2v, fft, c2mag, self.stats)
示例#44
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))
示例#45
0
    def __init__(self, fft_length, cp_length, snr, kstime, logging):
        ''' Maximum Likelihood OFDM synchronizer:
        J. van de Beek, M. Sandell, and P. O. Borjesson, "ML Estimation
        of Time and Frequency Offset in OFDM Systems," IEEE Trans.
        Signal Processing, vol. 45, no. 7, pp. 1800-1805, 1997.
        '''

	gr.hier_block2.__init__(self, "ofdm_sync_ml",
				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)

        SNR = 10.0**(snr/10.0)
        rho = SNR / (SNR + 1.0)
        symbol_length = fft_length + cp_length

        # ML Sync

        # Energy Detection from ML Sync

        self.connect(self, self.input)

        # Create a delay line
        self.delay = gr.delay(gr.sizeof_gr_complex, fft_length)
        self.connect(self.input, self.delay)

        # magnitude squared blocks
        self.magsqrd1 = gr.complex_to_mag_squared()
        self.magsqrd2 = gr.complex_to_mag_squared()
        self.adder = gr.add_ff()

        moving_sum_taps = [rho/2 for i in range(cp_length)]
        self.moving_sum_filter = gr.fir_filter_fff(1,moving_sum_taps)
        
        self.connect(self.input,self.magsqrd1)
        self.connect(self.delay,self.magsqrd2)
        self.connect(self.magsqrd1,(self.adder,0))
        self.connect(self.magsqrd2,(self.adder,1))
        self.connect(self.adder,self.moving_sum_filter)
        

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

        movingsum2_taps = [1.0 for i in range(cp_length)]
        self.movingsum2 = gr.fir_filter_ccf(1,movingsum2_taps)
        
        # Correlator data handler
        self.c2mag = gr.complex_to_mag()
        self.angle = gr.complex_to_arg()
        self.connect(self.input,(self.mixer,1))
        self.connect(self.delay,self.conjg,(self.mixer,0))
        self.connect(self.mixer,self.movingsum2,self.c2mag)
        self.connect(self.movingsum2,self.angle)

        # ML Sync output arg, need to find maximum point of this
        self.diff = gr.sub_ff()
        self.connect(self.c2mag,(self.diff,0))
        self.connect(self.moving_sum_filter,(self.diff,1))

        #ML measurements input to sampler block and detect
        self.f2c = gr.float_to_complex()
        self.pk_detect = gr.peak_detector_fb(0.2, 0.25, 30, 0.0005)
        self.sample_and_hold = gr.sample_and_hold_ff()

        # use the sync loop values to set the sampler and the NCO
        #     self.diff = theta
        #     self.angle = epsilon
                          
        self.connect(self.diff, self.pk_detect)

        # The DPLL corrects for timing differences between CP correlations
        use_dpll = 0
        if use_dpll:
            self.dpll = gr.dpll_bb(float(symbol_length),0.01)
            self.connect(self.pk_detect, self.dpll)
            self.connect(self.dpll, (self.sample_and_hold,1))
        else:
            self.connect(self.pk_detect, (self.sample_and_hold,1))
            
        self.connect(self.angle, (self.sample_and_hold,0))

        ################################
        # correlate against known symbol
        # This gives us the same timing signal as the PN sync block only on the preamble
        # we don't use the signal generated from the CP correlation because we don't want
        # to readjust the timing in the middle of the packet or we ruin the equalizer settings.
        kstime = [k.conjugate() for k in kstime]
        kstime.reverse()
        self.kscorr = gr.fir_filter_ccc(1, kstime)
        self.corrmag = gr.complex_to_mag_squared()
        self.div = gr.divide_ff()

        # The output signature of the correlation has a few spikes because the rest of the
        # system uses the repeated preamble symbol. It needs to work that generically if 
        # anyone wants to use this against a WiMAX-like signal since it, too, repeats.
        # The output theta of the correlator above is multiplied with this correlation to
        # identify the proper peak and remove other products in this cross-correlation
        self.threshold_factor = 0.1
        self.slice = gr.threshold_ff(self.threshold_factor, self.threshold_factor, 0)
        self.f2b = gr.float_to_char()
        self.b2f = gr.char_to_float()
        self.mul = gr.multiply_ff()
        
        # Normalize the power of the corr output by the energy. This is not really needed
        # and could be removed for performance, but it makes for a cleaner signal.
        # if this is removed, the threshold value needs adjustment.
        self.connect(self.input, self.kscorr, self.corrmag, (self.div,0))
        self.connect(self.moving_sum_filter, (self.div,1))
        
        self.connect(self.div, (self.mul,0))
        self.connect(self.pk_detect, self.b2f, (self.mul,1))
        self.connect(self.mul, self.slice)
        
        # Set output signals
        #    Output 0: fine frequency correction value
        #    Output 1: timing signal
        self.connect(self.sample_and_hold, (self,0))
        self.connect(self.slice, self.f2b, (self,1))


        if logging:
            self.connect(self.moving_sum_filter, gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-energy_f.dat"))
            self.connect(self.diff, gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-theta_f.dat"))
            self.connect(self.angle, gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-epsilon_f.dat"))
            self.connect(self.corrmag, gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-corrmag_f.dat"))
            self.connect(self.kscorr, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_ml-kscorr_c.dat"))
            self.connect(self.div, gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-div_f.dat"))
            self.connect(self.mul, gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-mul_f.dat"))
            self.connect(self.slice, gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-slice_f.dat"))
            self.connect(self.pk_detect, gr.file_sink(gr.sizeof_char, "ofdm_sync_ml-peaks_b.dat"))
            if use_dpll:
                self.connect(self.dpll, gr.file_sink(gr.sizeof_char, "ofdm_sync_ml-dpll_b.dat"))

            self.connect(self.sample_and_hold, gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-sample_and_hold_f.dat"))
            self.connect(self.input, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_ml-input_c.dat"))
    def __init__(self):
        gr.top_block.__init__(self)

        # Build an options parser to bring in information from the user on usage
        usage = "usage: %prog [options] host min_freq max_freq"
        parser = OptionParser(option_class=eng_option, usage=usage)
        parser.add_option("-g", "--gain", type="eng_float", default=32,
                          help="set gain in dB (default is midpoint)")
        parser.add_option("", "--tune-delay", type="eng_float", default=5e-5, metavar="SECS",
                          help="time to delay (in seconds) after changing frequency [default=%default]")
        parser.add_option("", "--dwell-delay", type="eng_float", default=50e-5, metavar="SECS",
                          help="time to dwell (in seconds) at a given frequncy [default=%default]")
        parser.add_option("-F", "--fft-size", type="int", default=256,
                          help="specify number of FFT bins [default=%default]")
        parser.add_option("-d", "--decim", type="intx", default=16,
                          help="set decimation to DECIM [default=%default]")
        parser.add_option("", "--real-time", action="store_true", default=False,
                          help="Attempt to enable real-time scheduling")

        (options, args) = parser.parse_args()
        if len(args) != 3:
            parser.print_help()
            sys.exit(1)

        # get user-provided info on address of MSDD and frequency to sweep
        self.address  = args[0]
        self.min_freq = eng_notation.str_to_num(args[1])
        self.max_freq = eng_notation.str_to_num(args[2])

        self.decim = options.decim
        self.gain  = options.gain
        
        if self.min_freq > self.max_freq:
            self.min_freq, self.max_freq = self.max_freq, self.min_freq   # swap them

	self.fft_size = options.fft_size

        if not options.real_time:
            realtime = False
        else:
            # Attempt to enable realtime scheduling
            r = gr.enable_realtime_scheduling()
            if r == gr.RT_OK:
                realtime = True
            else:
                realtime = False
                print "Note: failed to enable realtime scheduling"

        # Sampling rate is hardcoded and cannot be read off device
        adc_rate = 102.4e6
        self.int_rate = adc_rate / self.decim
        print "Sampling rate: ", self.int_rate

        # build graph
        self.port = 10001   # required port for UDP packets
	
	#	which board,	op mode,	adx,	port
#        self.src = msdd.source_c(0, 1, self.address, self.port)  # build source object

	self.conv = gr.interleaved_short_to_complex();

	self.src = msdd.source_simple(self.address,self.port);
        self.src.set_decim_rate(self.decim)                      # set decimation rate
#        self.src.set_desired_packet_size(0, 1460)                # set packet size to collect

        self.set_gain(self.gain)                                 # set receiver's attenuation
        self.set_freq(self.min_freq)                             # set receiver's rx frequency
        
        # restructure into vector format for FFT input
	s2v = gr.stream_to_vector(gr.sizeof_gr_complex, self.fft_size)

        # set up FFT processing block
        mywindow = window.blackmanharris(self.fft_size)
        fft = gr.fft_vcc(self.fft_size, True, mywindow, True)
        power = 0
        for tap in mywindow:
            power += tap*tap
        
        # calculate magnitude squared of output of FFT
        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 % of the actual data throughput.
        # This allows us to discard the bins on both ends of the spectrum.
        self.percent = 0.4

        # Calculate the frequency steps to use in the collection over the whole bandwidth
        self.freq_step = self.percent * self.int_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.next_freq = self.min_center_freq
        
        # use these values to set receiver settling time between samples and sampling time
        # the default values provided seem to work well with the MSDD over 100 Mbps ethernet
        tune_delay  = max(0, int(round(options.tune_delay * self.int_rate / self.fft_size)))  # in fft_frames
        dwell_delay = max(1, int(round(options.dwell_delay * self.int_rate / self.fft_size))) # in fft_frames

        # set up message callback routine to get data from bin_statistics_f block
        self.msgq = gr.msg_queue(16)
        self._tune_callback = tune(self)        # hang on to this to keep it from being GC'd

        # FIXME this block doesn't like to work with negatives because of the "d_max[i]=0" on line
        # 151 of gr_bin_statistics_f.cc file. Set this to -10000 or something to get it to work.
        stats = gr.bin_statistics_f(self.fft_size, self.msgq,
                                    self._tune_callback, tune_delay, dwell_delay)

        # FIXME there's a concern over the speed of the log calculation
        # We can probably calculate the log inside the stats block
	self.connect(self.src, self.conv, s2v, fft, c2mag, log, stats)
示例#47
0
    def __init__(self):
        gr.top_block.__init__(self)

        usage = "usage: %prog [options] min_freq max_freq"
        parser = OptionParser(option_class=eng_option, usage=usage)
        parser.add_option("-a", "--args", type="string", default="",
                          help="UHD device device address args [default=%default]")
        parser.add_option("", "--spec", type="string", default=None,
	                  help="Subdevice of UHD device where appropriate")
        parser.add_option("-A", "--antenna", type="string", default=None,
                          help="select Rx Antenna where appropriate")
        parser.add_option("-s", "--samp-rate", type="eng_float", default=1e6,
                          help="set sample rate [default=%default]")
        parser.add_option("-g", "--gain", type="eng_float", default=None,
                          help="set gain in dB (default is midpoint)")
        parser.add_option("", "--tune-delay", type="eng_float",
                          default=1e-3, metavar="SECS",
                          help="time to delay (in seconds) after changing frequency [default=%default]")
        parser.add_option("", "--dwell-delay", type="eng_float",
                          default=10e-3, metavar="SECS",
                          help="time to dwell (in seconds) at a given frequency [default=%default]")
        parser.add_option("", "--channel-bandwidth", type="eng_float",
                          default=12.5e3, metavar="Hz",
                          help="channel bandwidth of fft bins in Hz [default=%default]")
        parser.add_option("-F", "--fft-size", type="int", default=256,
                          help="specify number of FFT bins [default=%default]")
        parser.add_option("", "--real-time", action="store_true", default=False,
                          help="Attempt to enable real-time scheduling")

        (options, args) = parser.parse_args()
        if len(args) != 2:
            parser.print_help()
            sys.exit(1)

        self.min_freq = eng_notation.str_to_num(args[0])
        self.max_freq = eng_notation.str_to_num(args[1])

        if self.min_freq > self.max_freq:
            # swap them
            self.min_freq, self.max_freq = self.max_freq, self.min_freq

        self.fft_size = options.fft_size
        self.channel_bandwidth = options.channel_bandwidth
        
        if not options.real_time:
            realtime = False
        else:
            # Attempt to enable realtime scheduling
            r = gr.enable_realtime_scheduling()
            if r == gr.RT_OK:
                realtime = True
            else:
                realtime = False
                print "Note: failed to enable realtime scheduling"

        # build graph
        self.u = uhd.usrp_source(device_addr=options.args,
                                 stream_args=uhd.stream_args('fc32'))

        # Set the subdevice spec
        if(options.spec):
            self.u.set_subdev_spec(options.spec, 0)

        # Set the antenna
        if(options.antenna):
            self.u.set_antenna(options.antenna, 0)

        self.usrp_rate = usrp_rate = options.samp_rate
        self.u.set_samp_rate(usrp_rate)
        dev_rate = self.u.get_samp_rate()

        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, True)
        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.next_freq = self.min_center_freq

        tune_delay  = max(0, int(round(options.tune_delay * usrp_rate / self.fft_size)))  # in fft_frames
        dwell_delay = max(1, int(round(options.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)

        # FIXME leave out the log10 until we speed it up
        #self.connect(self.u, s2v, fft, c2mag, log, stats)
        self.connect(self.u, s2v, fft, c2mag, stats)

        if options.gain is None:
            # if no gain was specified, use the mid-point in dB
            g = self.u.get_gain_range()
            options.gain = float(g.start()+g.stop())/2.0

        self.set_gain(options.gain)
        print "gain =", options.gain
示例#48
0
    def __init__(self, fft_length, cp_length, half_sync, logging=False):
        gr.hier_block2.__init__(
            self,
            "ofdm_sync_pn",
            gr.io_signature(1, 1, gr.sizeof_gr_complex),  # Input signature
            gr.io_signature3(
                3,
                3,  # Output signature
                gr.sizeof_gr_complex,  # delayed input
                gr.sizeof_float,  # fine frequency offset
                gr.sizeof_char  # timing indicator
            ))

        if half_sync:
            period = fft_length / 2
            window = fft_length / 2
        else:  # full symbol
            period = fft_length + cp_length
            window = fft_length  # makes the plateau cp_length long

        # Calculate the frequency offset from the correlation of the preamble
        x_corr = gr.multiply_cc()
        self.connect(self, gr.conjugate_cc(), (x_corr, 0))
        self.connect(self, gr.delay(gr.sizeof_gr_complex, period), (x_corr, 1))
        P_d = gr.moving_average_cc(window, 1.0)
        self.connect(x_corr, P_d)

        P_d_angle = gr.complex_to_arg()
        self.connect(P_d, P_d_angle)

        # Get the power of the input signal to normalize the output of the correlation
        R_d = gr.moving_average_ff(window, 1.0)
        self.connect(self, gr.complex_to_mag_squared(), R_d)
        R_d_squared = gr.multiply_ff()  # this is retarded
        self.connect(R_d, (R_d_squared, 0))
        self.connect(R_d, (R_d_squared, 1))
        M_d = gr.divide_ff()
        self.connect(P_d, gr.complex_to_mag_squared(), (M_d, 0))
        self.connect(R_d_squared, (M_d, 1))

        # Now we need to detect peak of M_d

        # NOTE: replaced fir_filter with moving_average for clarity
        # the peak is up to cp_length long, but noisy, so average it out
        #matched_filter_taps = [1.0/cp_length for i in range(cp_length)]
        #matched_filter = gr.fir_filter_fff(1, matched_filter_taps)
        matched_filter = gr.moving_average_ff(cp_length, 1.0 / cp_length)

        # NOTE: the look_ahead parameter doesn't do anything
        # these parameters are kind of magic, increase 1 and 2 (==) to be more tolerant
        #peak_detect = raw.peak_detector_fb(0.55, 0.55, 30, 0.001)
        peak_detect = raw.peak_detector_fb(0.25, 0.25, 30, 0.001)
        # NOTE: gr.peak_detector_fb is broken!
        #peak_detect = gr.peak_detector_fb(0.55, 0.55, 30, 0.001)
        #peak_detect = gr.peak_detector_fb(0.45, 0.45, 30, 0.001)
        #peak_detect = gr.peak_detector_fb(0.30, 0.30, 30, 0.001)

        # offset by -1
        self.connect(M_d, matched_filter, gr.add_const_ff(-1), peak_detect)

        # peak_detect indicates the time M_d is highest, which is the end of the symbol.
        # We should try to sample in the middle of the plateau!!
        # FIXME until we figure out how to do this, just offset by cp_length/2
        offset = 6  #cp_length/2

        # nco(t) = P_d_angle(t-offset) sampled at peak_detect(t)
        # modulate input(t - fft_length) by nco(t)
        # signal to sample input(t) at t-offset
        #
        # We can't delay by < 0 so instead:
        # input is delayed by fft_length
        # P_d_angle is delayed by offset
        # signal to sample is delayed by fft_length - offset
        #
        phi = gr.sample_and_hold_ff()
        self.connect(peak_detect, (phi, 1))
        self.connect(P_d_angle, gr.delay(gr.sizeof_float, offset), (phi, 0))
        #self.connect(P_d_angle, matched_filter2, (phi,0)) # why isn't this better?!?

        # FIXME: we add fft_length delay so that the preamble is nco corrected too
        # BUT is this buffering worth it? consider implementing sync as a proper block

        # delay the input signal to follow the frequency offset signal
        self.connect(self, gr.delay(gr.sizeof_gr_complex,
                                    (fft_length + offset)), (self, 0))
        self.connect(phi, (self, 1))
        self.connect(peak_detect, (self, 2))

        if logging:
            self.connect(matched_filter,
                         gr.file_sink(gr.sizeof_float, "sync-mf.dat"))
            self.connect(M_d, gr.file_sink(gr.sizeof_float, "sync-M.dat"))
            self.connect(P_d_angle,
                         gr.file_sink(gr.sizeof_float, "sync-angle.dat"))
            self.connect(peak_detect,
                         gr.file_sink(gr.sizeof_char, "sync-peaks.datb"))
            self.connect(phi, gr.file_sink(gr.sizeof_float, "sync-phi.dat"))
示例#49
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)
示例#50
0
    def __init__(self, usrp_rate, tuner_callback, options):
        gr.hier_block2.__init__(self, "sense_path",
                gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
                gr.io_signature(0, 0, 0)) # Output signature
        
        self.usrp_rate = usrp_rate
        self.usrp_tune = tuner_callback

        self.num_tests = options.num_tests
            
        self.threshold = options.threshold
        
        self.min_freq = options.start_freq
        self.max_freq = options.end_freq

        if self.min_freq > self.max_freq:
            self.min_freq, self.max_freq = self.max_freq, self.min_freq   # swap them
            
        self.fft_size = options.fft_size


        if not options.real_time:
            realtime = False
        else:
            # Attempt to enable realtime scheduling
            r = gr.enable_realtime_scheduling()
            if r == gr.RT_OK:
                realtime = True
            else:
                realtime = False
                print "Note: failed to enable realtime scheduling"

        # build graph
        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.

        #changed on 2011 May 31, MR -- maybe change back at some point
        self.freq_step = self.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.next_freq = self.min_center_freq
        
        tune_delay  = max(0, int(round(options.tune_delay * self.usrp_rate / self.fft_size)))  # in fft_frames
        dwell_delay = max(1, int(round(options.dwell_delay * self.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)

        # FIXME leave out the log10 until we speed it up
        #self.connect(self, s2v, fft, c2mag, log, stats)
        self.connect(self, s2v, fft, c2mag, stats)
示例#51
0
    def __init__(self, subc, vlen, ss):
        gr.hier_block2.__init__(
            self, "new_snr_estimator",
            gr.io_signature(1, 1, gr.sizeof_gr_complex * vlen),
            gr.io_signature(1, 1, gr.sizeof_float))

        print "Created Milan's SNR estimator"

        trigger = [0] * vlen
        trigger[0] = 1

        u = range(vlen / ss * (ss - 1))
        zeros_ind = map(lambda z: z + 1 + z / (ss - 1), u)

        skip1 = skip(gr.sizeof_gr_complex, vlen)
        for x in zeros_ind:
            skip1.skip(x)

        #print "skipped zeros",zeros_ind

        v = range(vlen / ss)
        ones_ind = map(lambda z: z * ss, v)

        skip2 = skip(gr.sizeof_gr_complex, vlen)
        for x in ones_ind:
            skip2.skip(x)

        #print "skipped ones",ones_ind

        v2s = gr.vector_to_stream(gr.sizeof_gr_complex, vlen)
        s2v1 = gr.stream_to_vector(gr.sizeof_gr_complex, vlen / ss)
        trigger_src_1 = gr.vector_source_b(trigger, True)

        s2v2 = gr.stream_to_vector(gr.sizeof_gr_complex, vlen / ss * (ss - 1))
        trigger_src_2 = gr.vector_source_b(trigger, True)

        mag_sq_ones = gr.complex_to_mag_squared(vlen / ss)
        mag_sq_zeros = gr.complex_to_mag_squared(vlen / ss * (ss - 1))

        filt_ones = gr.single_pole_iir_filter_ff(0.1, vlen / ss)
        filt_zeros = gr.single_pole_iir_filter_ff(0.1, vlen / ss * (ss - 1))

        sum_ones = vector_sum_vff(vlen / ss)
        sum_zeros = vector_sum_vff(vlen / ss * (ss - 1))

        D = gr.divide_ff()
        P = gr.multiply_ff()
        mult1 = gr.multiply_const_ff(ss - 1.0)
        add1 = gr.add_const_ff(-1.0)
        mult2 = gr.multiply_const_ff(1. / ss)
        scsnrdb = gr.nlog10_ff(10, 1, 0)
        filt_end = gr.single_pole_iir_filter_ff(0.1)

        self.connect(self, v2s, skip1, s2v1, mag_sq_ones, filt_ones, sum_ones)
        self.connect(trigger_src_1, (skip1, 1))

        self.connect(v2s, skip2, s2v2, mag_sq_zeros, filt_zeros, sum_zeros)
        self.connect(trigger_src_2, (skip2, 1))

        self.connect(sum_ones, D)
        self.connect(sum_zeros, (D, 1))
        self.connect(D, mult1, add1, mult2)

        self.connect(mult2, scsnrdb, filt_end, self)
示例#52
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"))
示例#53
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"))
示例#54
0
    def __init__(self):
        gr.top_block.__init__(self)

        usage = "usage: %prog [options] host min_freq max_freq"
        parser = OptionParser(option_class=eng_option, usage=usage)
        parser.add_option("-g", "--gain", type="eng_float", default=None,
                          help="set gain in dB (default is midpoint)")
        parser.add_option("", "--tune-delay", type="eng_float", default=5e-5, metavar="SECS",
                          help="time to delay (in seconds) after changing frequency [default=%default]")
        parser.add_option("", "--dwell-delay", type="eng_float", default=50e-5, metavar="SECS",
                          help="time to dwell (in seconds) at a given frequncy [default=%default]")
        parser.add_option("-F", "--fft-size", type="int", default=256,
                          help="specify number of FFT bins [default=%default]")
        parser.add_option("-d", "--decim", type="intx", default=16,
                          help="set decimation to DECIM [default=%default]")
        parser.add_option("", "--real-time", action="store_true", default=False,
                          help="Attempt to enable real-time scheduling")

        (options, args) = parser.parse_args()
        if len(args) != 3:
            parser.print_help()
            sys.exit(1)

        self.address  = args[0]
        self.min_freq = eng_notation.str_to_num(args[1])
        self.max_freq = eng_notation.str_to_num(args[2])

        self.decim = options.decim
        self.gain  = options.gain
        
        if self.min_freq > self.max_freq:
            self.min_freq, self.max_freq = self.max_freq, self.min_freq   # swap them

	self.fft_size = options.fft_size

        if not options.real_time:
            realtime = False
        else:
            # Attempt to enable realtime scheduling
            r = gr.enable_realtime_scheduling()
            if r == gr.RT_OK:
                realtime = True
            else:
                realtime = False
                print "Note: failed to enable realtime scheduling"

        adc_rate = 102.4e6
        self.int_rate = adc_rate / self.decim
        print "Sampling rate: ", self.int_rate

        # build graph
        self.port = 10001
        self.src = msdd.source_simple(self.address, self.port)
        self.src.set_decim_rate(self.decim)

        self.set_gain(self.gain)
        self.set_freq(self.min_freq)

	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, True)
        power = 0
        for tap in mywindow:
            power += tap*tap
        
        norm = gr.multiply_const_cc(1.0/self.fft_size)
        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 % of the actual data throughput.
        # This allows us to discard the bins on both ends of the spectrum.
        self.percent = 0.4

        self.freq_step = self.percent * self.int_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.next_freq = self.min_center_freq
        
        tune_delay  = max(0, int(round(options.tune_delay * self.int_rate / self.fft_size)))  # in fft_frames
        dwell_delay = max(1, int(round(options.dwell_delay * self.int_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)

        # FIXME leave out the log10 until we speed it up
	self.connect(self.src, s2v, fft, c2mag, log, stats)
示例#55
0
    def __init__(self):
        gr.top_block.__init__(self)
        global parser
        parser = OptionParser(option_class=eng_option)
        parser.add_option("-a",
                          "--args",
                          type="string",
                          default="",
                          help="UHD device address [default=%default]")

        #parser.add_option("-e", "--interface", type="string", default="eth0", help="Select ethernet interface. Default is eth0")
        #parser.add_option("-m", "--MAC_addr", type="string", default="", help="Select USRP2 by its MAC address.Default is auto-select")
        parser.add_option("-p",
                          "--start",
                          type="eng_float",
                          default=1e7,
                          help="Start ferquency [default = %default]")
        parser.add_option("-q",
                          "--stop",
                          type="eng_float",
                          default=1e8,
                          help="Stop ferquency [default = %default]")
        parser.add_option(
            "",
            "--tune-delay",
            type="eng_float",
            default=1e-3,
            metavar="SECS",
            help=
            "time to delay (in seconds) after changing frequency[default=%default]"
        )
        parser.add_option(
            "",
            "--dwell-delay",
            type="eng_float",
            default=10e-3,
            metavar="SECS",
            help=
            "time to dwell (in seconds) at a given frequncy[default=%default]")
        parser.add_option("-g",
                          "--gain",
                          type="eng_float",
                          default=None,
                          help="set gain in dB (default is midpoint)")
        parser.add_option("-s",
                          "--fft-size",
                          type="int",
                          default=256,
                          help="specify number of FFT bins [default=%default]")
        parser.add_option("-d",
                          "--decim",
                          type="intx",
                          default=16,
                          help="set decimation to DECIM [default=%default]")
        parser.add_option("-i",
                          "--input_file",
                          default="",
                          help="radio input file",
                          metavar="FILE")
        parser.add_option(
            "-S",
            "--sense-bins",
            type="int",
            default=64,
            help="set number of bins in the OFDM block [default=%default]")
        (options, args) = parser.parse_args()
        if options.input_file == "":
            self.IS_USRP2 = True
        else:
            self.IS_USRP2 = False

        self.min_freq = options.start
        self.max_freq = options.stop
        print "min_freq=", self.min_freq
        print "max_freq=", self.max_freq

        if self.min_freq > self.max_freq:
            self.min_freq, self.max_freq = self.max_freq, self.min_freq  # swap them
            print "Start and stop frequencies order swapped!"
        self.fft_size = options.fft_size
        self.ofdm_bins = options.sense_bins
        # build graph
        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)
        #log = gr.nlog10_ff(10, self.fft_size, -20*math.log10(self.fft_size)-10*math.log10(power/self.fft_size))

        # modifications for USRP2
        print "*******************in sensor init********************"
        if self.IS_USRP2:

            self.u = uhd.usrp_source(device_addr=options.args,
                                     io_type=uhd.io_type.COMPLEX_FLOAT32,
                                     num_channels=1)

            samp_rate = 100**6 / options.decim
            self.u.set_samp_rate(samp_rate)

        else:
            self.u = gr.file_source(gr.sizeof_gr_complex, options.input_file,
                                    True)
            samp_rate = 100e6 / options.decim

        self.freq_step = 0  #0.75* samp_rate
        self.min_center_freq = (self.min_freq + self.max_freq) / 2

        global BW
        BW = self.max_freq - self.min_freq
        print "bandwidth=", BW
        global size
        size = self.fft_size

        global ofdm_bins
        ofdm_bins = self.ofdm_bins

        global usr
        #global thrshold_inorder

        usr = samp_rate
        nsteps = 10  #math.ceil((self.max_freq - self.min_freq) / self.freq_step)
        self.max_center_freq = self.min_center_freq + (nsteps * self.freq_step)
        self.next_freq = self.min_center_freq
        tune_delay = max(0,
                         int(
                             round(options.tune_delay * samp_rate /
                                   self.fft_size)))  # in fft_frames
        print tune_delay
        dwell_delay = max(1,
                          int(
                              round(options.dwell_delay * samp_rate /
                                    self.fft_size)))  # in fft_frames
        print dwell_delay
        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)
        self.connect(self.u, s2v, fft, c2mag, stats)
        if options.gain is None:
            # if no gain was specified, use the mid-point in dB
            g = self.u.get_gain_range()
            options.gain = float(g.start() + g.stop()) / 2
示例#56
0
def complex_to_mag_squared(N):
    op = gr.complex_to_mag_squared()
    tb = helper(N, op, gr.sizeof_gr_complex, gr.sizeof_float, 1, 1)
    return tb
示例#57
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)