⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usrp_psr_receiver.py

📁 这是用python语言写的一个数字广播的信号处理工具包。利用它
💻 PY
📖 第 1 页 / 共 3 页
字号:
#!/usr/bin/env python## Copyright 2004,2005 Free Software Foundation, Inc.# # This file is part of GNU Radio# # GNU Radio is free software; you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation; either version 3, or (at your option)# any later version.# # GNU Radio is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the# GNU General Public License for more details.# # You should have received a copy of the GNU General Public License# along with GNU Radio; see the file COPYING.  If not, write to# the Free Software Foundation, Inc., 51 Franklin Street,# Boston, MA 02110-1301, USA.# ### Pulsar receiver application## Performs both harmonic folding analysis#  and epoch folding analysis##from gnuradio import gr, gru, blks, audiofrom usrpm import usrp_dbidfrom gnuradio import usrp, optfirfrom gnuradio import eng_notationfrom gnuradio.eng_option import eng_optionfrom gnuradio.wxgui import stdgui, ra_fftsink, ra_stripchartsink, form, sliderfrom optparse import OptionParserimport wximport sysimport Numericimport FFTimport ephemimport timeimport osimport mathclass app_flow_graph(stdgui.gui_flow_graph):    def __init__(self, frame, panel, vbox, argv):        stdgui.gui_flow_graph.__init__(self)        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")        (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        # 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 4 pulses in the pulse viewer window        FOLD_MULT=1        # 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 (self, 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))        self.chart = ra_stripchartsink.stripchart_sink_f (self, panel,               sample_rate=1,               stripsize=self.folding*FOLD_MULT, parallel=True, title="Pulse Profiles: "+hz+per,                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        #        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)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -