diff options
90 files changed, 290 insertions, 6538 deletions
diff --git a/Makefile.common b/Makefile.common index 8faf64586..a4d5817ff 100644 --- a/Makefile.common +++ b/Makefile.common @@ -56,13 +56,6 @@ guiledir = $(prefix)/share/guile/site grpythondir = $(pythondir)/gnuradio grpyexecdir = $(pyexecdir)/gnuradio -# Install the non-gnuradio usrp stuff in the appropriate subdirectory -# This usually ends up at: -# ${prefix}/lib/python${python_version}/site-packages/usrpm - -usrppythondir = $(pythondir)/usrpm -usrppyexecdir = $(pyexecdir)/usrpm - # This used to be set in configure.ac but is now defined here for all # Makefiles when this fragment is included. STD_DEFINES_AND_INCLUDES = $(DEFINES) $(GNURADIO_INCLUDES) \ @@ -88,10 +81,6 @@ GRUEL_LA = @gruel_LA@ VOLK_INCLUDES = @volk_INCLUDES@ VOLK_LA = @volk_LA@ -# How to link in the USRP library from inside the tree -USRP_INCLUDES = @usrp_INCLUDES@ -USRP_LA = @usrp_LA@ - # GR-DIGITAL includes and libraries GR_DIGITAL_INCLUDES = @gr_digital_INCLUDES@ GR_DIGITAL_LA = @gr_digital_LA@ @@ -61,8 +61,8 @@ How to Build GNU Radio: On systems using pkgsrc (e.g. NetBSD and Dragonfly), build meta-packages/gnuradio, which will build a previous release and force installation of the dependencies. Then pkg_delete the - gnuradio and usrp packages, which will leave the dependencies. - (This should also work on OSX.) + gnuradio package, which will leave the dependencies. (This + should also work on OSX.) See the wiki at http://gnuradio.org/trac/wiki for details. @@ -192,11 +192,7 @@ As of repository version 4045, gnuradio requires version 1.3.31 or newer. (9) SDCC: Small Device C Compiler. http://sdcc.sourceforge.net/ -Use version 2.4.0 or later. - -This includes a C compiler and linker for the 8051. It's required to -build the firmware for the USRP. If you don't have a USRP, don't -worry about it. +--> Not required as of v3.5 (10) Guile 1.6 or 1.8 diff --git a/README-win32-mingw-short.txt b/README-win32-mingw-short.txt index 88338e3b7..9001e9f15 100644 --- a/README-win32-mingw-short.txt +++ b/README-win32-mingw-short.txt @@ -86,7 +86,7 @@ make make install Now you have a working gnuradio-core -Now you can go on building and installing gr-audio-windows and windows usrp and wxgui +Now you can go on building and installing gr-audio-windows and windows and wxgui remember that all gnuradio and python dlls need to be on your path to use gnuradio The gnuradio dlls are installed at /c/Python24/Lib/site-packages:/c/Python24/Lib/site-packages/gnuradio:/c/Python24/Lib/site-packages/gnuradio/gr diff --git a/README.hacking b/README.hacking index ff01a0a53..de6358abf 100644 --- a/README.hacking +++ b/README.hacking @@ -92,8 +92,6 @@ These are the current package prefixes: atsc_ Code related to the Advanced Television Standards Committee HDTV implementation - usrp_ Universal Software Radio Peripheral - qa_ Quality Assurance. Test code. @@ -220,32 +218,6 @@ into the help string using the "... [default=%default]" syntax. ** Mandatory options by gr_block -*** USRP source - -Any program using a USRP source (usrp.source_*) shall include: - - add_option("", "--which-usrp", type="intx", default=0, - help="select which USRP to use [default=%default]") - - add_option("-R", "--rx-subdev-spec", type="subdev", default=(0, 0), - help="select USRP Rx side A or B [default=A]") - -You are free to change the default if it makes sense in your application. - - -*** USRP sink - -Any program using a USRP sink (usrp.sink_*) shall include: - - add_option("", "--which-usrp", type="intx", default=0, - help="select which USRP to use [default=%default]") - - add_option("-T", "--tx-subdev-spec", type="subdev", default=(0, 0), - help="select USRP Tx side A or B [default=A]") - -You are free to change the default if it makes sense in your application. - - *** Audio source Any program using an audio source shall include: @@ -30,5 +30,4 @@ automake --add-missing -Wno-portability -Wno-override -Wnone #automake --add-missing -Wno-portability # Run bootstrap in any subprojects -(cd usrp2/firmware ; ./bootstrap) (cd volk ; ./bootstrap) diff --git a/config/Makefile.am b/config/Makefile.am index d2cb02865..003a0f6ae 100644 --- a/config/Makefile.am +++ b/config/Makefile.am @@ -53,9 +53,7 @@ m4macros = \ grc_gr_audio.m4 \ grc_gr_comedi.m4 \ grc_gr_noaa.m4 \ - grc_gr_radio_astronomy.m4 \ grc_gr_trellis.m4 \ - grc_gr_usrp.m4 \ grc_gr_video_sdl.m4 \ grc_gr_vocoder.m4 \ grc_gr_wxgui.m4 \ @@ -63,9 +61,6 @@ m4macros = \ gr_check_createfilemapping.m4 \ gr_check_mc4020.m4 \ gr_check_shm_open.m4 \ - gr_check_usrp.m4 \ - grc_usrp.m4 \ - grc_usrp2.m4 \ gr_doxygen.m4 \ gr_fortran.m4 \ gr_git.m4 \ @@ -91,9 +86,6 @@ m4macros = \ mkstemp.m4 \ onceonly.m4 \ pkg.m4 \ - sdl.m4 \ - usrp_fusb_tech.m4 \ - usrp_libusb.m4 \ - usrp_sdcc.m4 + sdl.m4 EXTRA_DIST += $(m4macros) diff --git a/config/grc_gnuradio_examples.m4 b/config/grc_gnuradio_examples.m4 index f6e964765..e60442170 100644 --- a/config/grc_gnuradio_examples.m4 +++ b/config/grc_gnuradio_examples.m4 @@ -29,7 +29,6 @@ AC_DEFUN([GRC_GNURADIO_EXAMPLES],[ gnuradio-examples/python/Makefile \ gnuradio-examples/grc/Makefile \ gnuradio-examples/python/mp-sched/Makefile \ - gnuradio-examples/python/multi_usrp/Makefile \ gnuradio-examples/python/network/Makefile \ gnuradio-examples/python/pfb/Makefile \ gnuradio-examples/python/tags/Makefile \ diff --git a/config/grc_gr_radio_astronomy.m4 b/config/grc_gr_radio_astronomy.m4 deleted file mode 100644 index 0affe5d78..000000000 --- a/config/grc_gr_radio_astronomy.m4 +++ /dev/null @@ -1,38 +0,0 @@ -dnl Copyright 2001,2002,2003,2004,2005,2006,2008 Free Software Foundation, Inc. -dnl -dnl This file is part of GNU Radio -dnl -dnl GNU Radio is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3, or (at your option) -dnl any later version. -dnl -dnl GNU Radio is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with GNU Radio; see the file COPYING. If not, write to -dnl the Free Software Foundation, Inc., 51 Franklin Street, -dnl Boston, MA 02110-1301, USA. - -AC_DEFUN([GRC_GR_RADIO_ASTRONOMY],[ - GRC_ENABLE(gr-radio-astronomy) - - dnl Don't do gr-radio-astronomy if gnuradio-core skipped - GRC_CHECK_DEPENDENCY(gr-radio-astronomy, gnuradio-core) - - AC_CONFIG_FILES([\ - gr-radio-astronomy/Makefile \ - gr-radio-astronomy/src/Makefile \ - gr-radio-astronomy/src/lib/Makefile \ - gr-radio-astronomy/src/python/Makefile \ - gr-radio-astronomy/src/python/run_tests \ - ]) - - GRC_BUILD_CONDITIONAL(gr-radio-astronomy,[ - dnl run_tests is created from run_tests.in. Make it executable. - AC_CONFIG_COMMANDS([run_tests_astronomy], [chmod +x gr-radio-astronomy/src/python/run_tests]) - ]) -]) diff --git a/config/grc_gr_uhd.m4 b/config/grc_gr_uhd.m4 index 0da087c48..11956b91a 100644 --- a/config/grc_gr_uhd.m4 +++ b/config/grc_gr_uhd.m4 @@ -52,7 +52,6 @@ AC_DEFUN([GRC_GR_UHD],[ gr-uhd/apps/hf_explorer/Makefile \ gr-uhd/apps/hf_radio/Makefile \ gr-uhd/examples/Makefile \ - gr-uhd/examples/multi-antenna/Makefile \ gr-uhd/doc/Makefile \ ]) diff --git a/config/grc_gr_utils.m4 b/config/grc_gr_utils.m4 index 7fe07d854..cb71ad18b 100644 --- a/config/grc_gr_utils.m4 +++ b/config/grc_gr_utils.m4 @@ -20,9 +20,8 @@ AC_DEFUN([GRC_GR_UTILS],[ GRC_ENABLE(gr-utils) - dnl Don't do gr-utils if gnuradio-core, usrp, or gr-wxgui skipped + dnl Don't do gr-utils if gnuradio-core or gr-wxgui skipped GRC_CHECK_DEPENDENCY(gr-utils, gnuradio-core) - GRC_CHECK_DEPENDENCY(gr-utils, usrp) GRC_CHECK_DEPENDENCY(gr-utils, gr-wxgui) AC_CONFIG_FILES([ \ diff --git a/configure.ac b/configure.ac index 531f9adb6..432c398d9 100644 --- a/configure.ac +++ b/configure.ac @@ -352,17 +352,12 @@ GRC_GRUEL dnl must come first GRC_VOLK GRC_GNURADIO_CORE GRC_GR_DIGITAL -GRC_USRP -GRC_USRP2 -GRC_GR_USRP dnl this must come after GRC_USRP -GRC_GR_USRP2 GRC_GR_AUDIO GRC_GR_VOCODER GRC_GR_ATSC GRC_GR_COMEDI GRC_GR_NOAA GRC_GR_PAGER -GRC_GR_RADIO_ASTRONOMY GRC_GR_TRELLIS GRC_GR_VIDEO_SDL GRC_GR_WXGUI diff --git a/docs/doxygen/Doxyfile.in b/docs/doxygen/Doxyfile.in index 356ababfe..efdacba32 100644 --- a/docs/doxygen/Doxyfile.in +++ b/docs/doxygen/Doxyfile.in @@ -625,49 +625,19 @@ EXCLUDE = @abs_top_builddir@/docs/doxygen/html \ @abs_top_builddir@/gr-audio-alsa/src/audio-alsa.py \ @abs_top_builddir@/gr-audio-oss/src/audio_oss.py \ @abs_top_builddir@/gr-audio-osx/src/test_audio_loop.py \ - @abs_top_builddir@/gr-cvsd-vocoder/src/lib/cvsd_vocoder.py \ - @abs_top_builddir@/gr-cvsd-vocoder/src/python/encdec.py \ @abs_top_builddir@/gr-gsm-fr-vocoder/src/lib/gsm \ @abs_top_builddir@/gr-gsm-fr-vocoder/src/lib/gsm_full_rate.py \ @abs_top_builddir@/gr-gsm-fr-vocoder/src/python/encdec.py \ @abs_top_builddir@/gr-howto-write-a-block \ - @abs_top_builddir@/gr-msdd6000/src/msdd.py \ @abs_top_builddir@/gr-pager/src/pager_swig.py \ @abs_top_builddir@/gr-qtgui \ - @abs_top_builddir@/gr-radar-mono/src/python/usrp_radar_mono.py \ - @abs_top_builddir@/gr-radio-astronomy/src/lib/ra.py \ - @abs_top_builddir@/gr-radio-astronomy/src/python \ - @abs_top_builddir@/gr-sounder/src/python/usrp_sounder.py \ @abs_top_builddir@/gr-trellis/doc \ @abs_top_builddir@/gr-trellis/src/lib/generate_all.py \ @abs_top_builddir@/gr-trellis/src/lib/generate_trellis.py \ @abs_top_builddir@/gr-trellis/src/lib/trellis.py \ - @abs_top_builddir@/gr-usrp/src/usrp1.py \ - @abs_top_builddir@/gr-usrp2/src/usrp2.py \ @abs_top_builddir@/gr-video-sdl/src/video_sdl.py \ @abs_top_builddir@/gr-wxgui/src/python \ - @abs_top_builddir@/grc \ - @abs_top_builddir@/usrp/doc \ - @abs_top_builddir@/usrp/firmware \ - @abs_top_builddir@/usrp/fpga \ - @abs_top_builddir@/usrp/host/apps \ - @abs_top_builddir@/usrp/host/apps-inband \ - @abs_top_builddir@/usrp/host/lib/inband \ - @abs_top_builddir@/usrp/host/lib/legacy/ad9862.h \ - @abs_top_builddir@/usrp/host/lib/legacy/check_data.py \ - @abs_top_builddir@/usrp/host/lib/legacy/circular_buffer.h \ - @abs_top_builddir@/usrp/host/lib/legacy/circular_linked_list.h \ - @abs_top_builddir@/usrp/host/lib/legacy/db_wbx.h \ - @abs_top_builddir@/usrp/host/lib/legacy/db_wbx.cc \ - @abs_top_builddir@/usrp/host/lib/legacy/dump_data.py \ - @abs_top_builddir@/usrp/host/lib/legacy/gen_usrp_dbid.py \ - @abs_top_builddir@/usrp/host/lib/legacy/usrp_dbid.py \ - @abs_top_builddir@/usrp/host/misc \ - @abs_top_builddir@/usrp/host/swig \ - @abs_top_builddir@/usrp2/firmware \ - @abs_top_srcdir@/usrp2/firmware \ - @abs_top_builddir@/usrp2/fpga \ - @abs_top_srcdir@/usrp2/fpga + @abs_top_builddir@/grc # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded @@ -700,7 +670,6 @@ EXCLUDE_PATTERNS = */.deps/* \ EXCLUDE_SYMBOLS = ad9862 \ numpy \ - usrpm \ *swig* \ *Swig* \ *my_top_block* \ diff --git a/docs/doxygen/other/group_defs.dox b/docs/doxygen/other/group_defs.dox index 6288d1f0a..b0b1994ff 100644 --- a/docs/doxygen/other/group_defs.dox +++ b/docs/doxygen/other/group_defs.dox @@ -68,7 +68,4 @@ /*! @} */ -/*! \defgroup usrp USRP */ -/*! \defgroup usrp2 USRP2 */ - /*! \defgroup hardware Misc Hardware Control */ diff --git a/gnuradio-core/src/python/gnuradio/Makefile.am b/gnuradio-core/src/python/gnuradio/Makefile.am index 066cc6d73..ffc171b2d 100644 --- a/gnuradio-core/src/python/gnuradio/Makefile.am +++ b/gnuradio-core/src/python/gnuradio/Makefile.am @@ -31,6 +31,5 @@ grpython_PYTHON = \ gr_unittest.py \ gr_xmlrunner.py \ optfir.py \ - usrp_options.py \ window.py endif diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/Makefile.am b/gnuradio-core/src/python/gnuradio/blks2impl/Makefile.am index 5c627b873..eb031cd20 100644 --- a/gnuradio-core/src/python/gnuradio/blks2impl/Makefile.am +++ b/gnuradio-core/src/python/gnuradio/blks2impl/Makefile.am @@ -33,7 +33,6 @@ grblkspython_PYTHON = \ filterbank.py \ fm_demod.py \ fm_emph.py \ - generic_usrp.py \ logpwrfft.py \ nbfm_rx.py \ nbfm_tx.py \ diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_fmdet.py b/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_fmdet.py index 3a93a11d6..14eaa1606 100755 --- a/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_fmdet.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_fmdet.py @@ -123,11 +123,10 @@ class wfm_rcv_fmdet(gr.hier_block2): self.rds_signal_generator = gr.multiply_cc(); self_rds_signal_processor = gr.null_sink(gr.sizeof_gr_complex); - alpha = 5 * 0.25 * math.pi / (audio_rate) - beta = alpha * alpha / 4.0 + loop_bw = 2*math.pi/100.0 max_freq = -2.0*math.pi*18990/audio_rate; min_freq = -2.0*math.pi*19010/audio_rate; - self.stereo_carrier_pll_recovery = gr.pll_refout_cc(alpha,beta, + self.stereo_carrier_pll_recovery = gr.pll_refout_cc(loop_bw, max_freq, min_freq); diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_pll.py b/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_pll.py index dd0fae6e7..a2c1b3651 100644 --- a/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_pll.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_pll.py @@ -47,11 +47,9 @@ class wfm_rcv_pll(gr.hier_block2): # if they need to. E.g., to plot its output. # # input: complex; output: float - alpha = 0.25*bandwidth * math.pi / demod_rate - beta = alpha * alpha / 4.0 + loop_bw = 2*math.pi/100.0 max_freq = 2.0*math.pi*90e3/demod_rate - - self.fm_demod = gr.pll_freqdet_cf (alpha,beta,max_freq,-max_freq) + self.fm_demod = gr.pll_freqdet_cf (loop_bw, max_freq,-max_freq) # input: float; output: float self.deemph_Left = fm_deemph (audio_rate) @@ -125,12 +123,11 @@ class wfm_rcv_pll(gr.hier_block2): - alpha = 5 * 0.25 * math.pi / (audio_rate) - beta = alpha * alpha / 4.0 + loop_bw = 2*math.pi/100.0 max_freq = -2.0*math.pi*18990/audio_rate; min_freq = -2.0*math.pi*19010/audio_rate; - self.stereo_carrier_pll_recovery = gr.pll_refout_cc(alpha,beta,max_freq,min_freq); + self.stereo_carrier_pll_recovery = gr.pll_refout_cc(loop_bw, max_freq, min_freq); #self.stereo_carrier_pll_recovery.squelch_enable(False) #pll_refout does not have squelch yet, so disabled for now diff --git a/gnuradio-examples/python/Makefile.am b/gnuradio-examples/python/Makefile.am index 80a319dd7..4327fd359 100644 --- a/gnuradio-examples/python/Makefile.am +++ b/gnuradio-examples/python/Makefile.am @@ -23,7 +23,6 @@ include $(top_srcdir)/Makefile.common SUBDIRS = \ mp-sched \ - multi_usrp \ network \ pfb \ tags diff --git a/gnuradio-examples/python/multi_usrp/.gitignore b/gnuradio-examples/python/multi_usrp/.gitignore deleted file mode 100644 index c400497f5..000000000 --- a/gnuradio-examples/python/multi_usrp/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -/Makefile -/Makefile.in -/.la -/.lo -/.deps -/.libs -/*.la -/*.lo -/*.pyc -/*.pyo diff --git a/gnuradio-examples/python/multi_usrp/Makefile.am b/gnuradio-examples/python/multi_usrp/Makefile.am deleted file mode 100644 index 2ef10b6e8..000000000 --- a/gnuradio-examples/python/multi_usrp/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright 2006,2009 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. -# - -include $(top_srcdir)/Makefile.common - -ourdatadir = $(exampledir)/multi_usrp - -dist_ourdata_DATA = \ - README - -dist_ourdata_SCRIPTS = \ - multi_usrp_oscope.py \ - multi_usrp_rx_cfile.py diff --git a/gnuradio-examples/python/multi_usrp/README b/gnuradio-examples/python/multi_usrp/README deleted file mode 100644 index 057239104..000000000 --- a/gnuradio-examples/python/multi_usrp/README +++ /dev/null @@ -1,266 +0,0 @@ -# -# N.B., these files have not been converted to top_block/hier_block2 because -# those of doing the conversion don't have the setup to test this. -# As a result, these programs will no longer run until updated. -# - -Quick start multi-usrp: - -Unpack, build and install usrp, gnuradio-core and gr-usrp -Versions need to be more recent then 2.7cvs/svn 11 may 2006 - -Make sure usrp/fpga/rbf/rev2/multi*.rbf is installed in /usr/local/share/usrp/rev2/ -Make sure usrp/fpga/rbf/rev4/multi*.rbf is installed in /usr/local/share/usrp/rev4/ -(If in doubt, copy manually) - -build and install gr-wxgui gr-audio-xxx and so on. - -unpack gnuradio-examples. - -There is a gnuradio-examples/python/multi_usrp directory which contains examples - - -Put at least a basic RX or dbsrx board in RXA of the master and RXA of the slave board. -Make sure that the usrps have a serial or unique identifier programmed in their eeprom. -(All new rev 4.1 boards have this) -You can do without a serial but then you never know which usrp is the master and which is the slave. - - -CONNECTING THE CABLES -Now connect the 64MHz clocks between the boards with a short sma coax cable. -(See the wiki on how to enable clock-out and clock-in -http://gnuradio.org/trac/wiki/USRPClockingNotes ) - -You need one board with a clock out and one board with a clock in. - -You can choose any of the two boards as master or slave, this is not dependant on which board has the clock-out or in. -In my experiments I had fewer problems when the board that has the clock-in will be the master board. - -You can use a standard 16-pole flatcable to connect tvrx, basic-rx or dbsrx boards. -Of this 16pin flatcable only two pins are used (io15 and ground) -For all new daughterboards which use up a lot of io pins you have to use a cable with fewer connections. -The savest is using a 2pin headercable connected to io15,gnd (a cable like the ones used to connect frontpanel leds to the mainboard of a PC) - -If using basic rx board: - Connect a 16-pole flatcable from J25 on basicrx/dbs_rx in rxa of the master usrp to J25 on basicrx/dbsrx in RXA of the slave usrp - Don't twist the cable (Make sure the pin1 marker (red line on the flatcable) is on the same side of the connector (at io-8 on the master and at io8 on the slave.)) - For basic_rx this means the marker should be on the side of the dboard with the sma connectors. - For dbs_rx this means the marker should be on the side of the dboard with the two little chips. - In other words, don't twist the cable, you will burn your board if you do. - -You can also connect a flatcable with multiple connectors from master-J25 to slave1-J25 to slave2-J25 to ... -You will however have to think of something to create a common 64Mhz clock for more then two usrps. - -For all other daughterboards, connect a 2wire cable from masterRXA J25 io15,gnd to slaveRXA J25 io15,gnd - - -So now the hardware is setup, software is setup. Lets do some tests. - -Connect power to both usrps. -unpack the gnuradio_examples somewhere (cvs version later then 11 may 2006) -go to the gnuradio-examples/python/multi_usrp folder. - -Now run - ./multi_usrp_oscope.py -x 12345678 - -It should tell you that usrp 12345678 is not found and tell you which serials are available. - -Now run ./multi_usrp_oscope.py -x actualserialnum -You should now get an oscope with two channels, one is from the master and one is from the slave -It will which show the I-signal from channel 0 of the master usrp and I-signal from channel 0 of the slave usrp. -(For testing connect the same signal source to the inputs of both boards) -The signals should be aligned. -If you click the sync button, it will resync the master and slave (should never be needed) - -Now run -./multi_usrp_oscope.py --help -To see all available options. - - -Now you are ready to do phase-locked aligned signal processing. - -You can also capture to file with: -./multi_usrp_rx_cfile.py - -run ./multi_usrp_rx_cfile.py --help to see all available options. - - - -Here follows a description of the detail blocks used in usrp_multi.py - -Multi usrp - -With this code you can connect two or more usrps (with a locked clock) and get synchronised samples. -You must connect a (flat)cable between a dboard on the master in RXA and a dboard on the slave in RXA. -You then put one usrp in master mode, put the other in slave mode. - -The easiest thing to see how this works is just looking at the code in - multi_usrp_oscope.py - multi_usrp_rx_cfile.py - -Use the usrp_multi block which is installed by gr-usrp. -instantiate in the following way: - - self.multi=usrp_multi.multi_source_align( fg=self, master_serialno=options.master_serialno, decim=options.decim, nchan=options.nchan ) - -nchan should be 2 or 4. - -You determine which is the master by master_serialno (this is a text string a hexadecimal number). -If you enter a serial number which is not found it will print the serial numbers which are available. -If you give no serial number (master_serialno=None), the code will pick a Master for you. - -You can get a reference to the master and the slave usrp in the following way: - - self.um=self.multi.get_master_usrp() - self.us=self.multi.get_slave_usrp() - -You only need these references for setting freqs/gains or getting info about daughterboards. -Don't use the output directly but use the aligned output from multi.get_master_source_c() and multi.get_slave_source_c() - -You get references to the aligned output samples in the following way: -aligned_master_source_c=self.multi.get_master_source_c() -aligned_slave_source_c=self.multi.get_slave_source_c() - -These blocks have multiple outputs. -output 0 is the sample counter (high bits in I, low bits in Q) -You normally don't need the samplecounters so you can ignore output 0 - -output 1 is the first aligend output channel (if you enable 2 or 4 channels) -output 2 is the second output channel (only if you enable 4 channels) - -so the usefull 4 channels are: -self.aligned_master_chan1=(self.multi.get_master_source_c(),1) -self.aligned_master_chan2=(self.multi.get_master_source_c(),2) -self.aligned_slave_chan1=(self.multi.get_slave_source_c(),1) -self.aligned_slave_chan2=(self.multi.get_slave_source_c(),2) - -The two samplecounters are: -self.aligned_master_samplecounter=(self.multi.get_master_source_c(),0) -self.aligned_slave_samplecounter=(self.multi.get_slave_source_c(),0) - -You can set the gain or tune the frequency for all 4 receive daughetrboards at once: - self.multi.set_gain_all_rx(options.gain) - result,r1,r2,r3,r4 = self.multi.tune_all_rx(options.freq) - -This will only work reliably when you have all the same daughterboards. -Otherwise set all freqs and gains individually. - -You must call self.multi.sync() at least once AFTER the flowgraph has started running. -(This will synchronise the streams of the two usrps) - -This work was funded by Toby Oliver at Sensus Analytics / Path Intelligence. -Many Thanks for making this possible. - -It was written by Martin Dudok van Heel at Olifantasia. - - - -Here follows a brief of the new blocks and (changes)functionality written for multi-usrp support. - -You can also look at the generated documentation in -/usr/local/share/doc/gnuradio-core-X.X -/usr/local/share/doc/usrp-X.X -(Make sure to build and install the documentation, go to the doc directory of the sourcetree and issue make doc; make install) - - -gnuradio-examples: -new/changed files: -multi_usrp/multi_usrp_oscope.py -multi_usrp/multi_usrp_rx_cfile.py - - -gnuradio-core: -gr.align_on_samplenumbers_ss (int nchan,int align_interval) - -align several complex short (interleaved short) input channels with corresponding unsigned 32 bit sample_counters (provided as interleaved 16 bit values) - -Parameters: - nchan number of complex_short input channels (including the 32 bit counting channel) - align_interval interval at which the samples are aligned, ignored for now. - -Pay attention on how you connect this block It expects a minimum of 2 usrp_source_s with nchan number of channels and as mode usrp_prims.bmFR_MODE_RX_COUNTING_32BIT enabled. This means that the first complex_short channel is an interleaved 32 bit counter. The samples are aligned by dropping samples untill the samplenumbers match. - -files: -gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.cc -gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.h -gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.i - - -gr-usrp - added _write_fpga_reg_masked - added usrp_multi.py - new usrp_multi block which can instantiate two linked usrps as master and slave and alignes their output. - It has a sync() function which should be called AFTER the flowgraph has started running. - bool sync(); - \brief Call this on a master usrp to sync master and slave by outputing a sync pulse on rx_a_io[15]. - The 32 bit samplecounter of master and slave will be reset to zero and all phase and buffer related things in the usrps are reset. - Call this only after the flowgraph has been started, otherwise there will be no effect since everything is kept in reset state as long as the flowgraph is not running. - \returns true if successfull. - -files: -configure.ac -src/Makefile.am -src/usrp1.i -src/usrp1_source_base.cc -src/usrp1_source_base.h -src/usrp_multi.py - -usrp-0.11cvsmulti: -usrp: - new constant bmFR_MODE_RX_COUNTING_32BIT (could also be added as extra mode like FPGA_MODE_COUNTING_32BIT) - Use this for the mode parameter when creating a usrp when you want to use the master/slave setup or if you want to use the 32 bit counter for other things, like testing with gr.check_counting_s(True) - - added register FR_RX_MASTER_SLAVE - added bitno and bitmaskes: - bmFR_MODE_RX_COUNTING_32BIT - - bitnoFR_RX_SYNC - bitnoFR_RX_SYNC_MASTER - bitnoFR_RX_SYNC_SLAVE - - bitnoFR_RX_SYNC_INPUT_IOPIN 15 - bmFR_RX_SYNC_INPUT_IOPIN (1<<bitnoFR_RX_SYNC_INPUT_IOPIN) - bitnoFR_RX_SYNC_OUTPUT_IOPIN 15 - bmFR_RX_SYNC_OUTPUT_IOPIN (1<<bitnoFR_RX_SYNC_OUTPUT_IOPIN) - - added _write_fpga_reg_masked() - added new toplevel folder usrp_multi - added usrp_multi.v and master_control_multi.v - added new MULTI_ON and COUNTER_32BIT_ON defines - If these are turned off usrp_multi.v will behave exactly as usrp_std.v - - added setting_reg_masked.v - changed reset behaviour of phase_acc.v and rx_buffer.v - - changed generate_regs.py to handle bm and bitno defines - - -files: -firmware/include/fpga_regs_standard.v -firmware/include/fpga_regs_common.h -firmware/include/generate_regs.py -firmware/include/fpga_regs_standard.h -host/lib/usrp_basic.h -host/lib/usrp_basic.cc -host/lib/usrp_standard.h -fpga/rbf/Makefile.am -fpga/toplevel/usrp_std/usrp_std.v -fpga/toplevel/usrp_multi/usrp_multi.esf -fpga/toplevel/usrp_multi/usrp_multi.vh -fpga/toplevel/usrp_multi/usrp_std.vh -fpga/toplevel/usrp_multi/usrp_multi_config_2rxhb_0tx.vh -fpga/toplevel/usrp_multi/usrp_multi_config_2rxhb_2tx.vh -fpga/toplevel/usrp_multi/usrp_multi.v -fpga/toplevel/usrp_multi/usrp_multi.qpf -fpga/toplevel/usrp_multi/usrp_multi.psf -fpga/toplevel/usrp_multi/usrp_multi_config_2rx_0tx.vh -fpga/toplevel/usrp_multi/usrp_multi.qsf -fpga/toplevel/usrp_multi/usrp_multi_config_4rx_0tx.vh -fpga/toplevel/usrp_multi/usrp_multi.csf -fpga/toplevel/usrp_multi/.cvsignore -fpga/sdr_lib/rx_buffer.v -fpga/sdr_lib/master_control_multi.v -fpga/sdr_lib/phase_acc.v -fpga/sdr_lib/setting_reg_masked.v - - diff --git a/gnuradio-examples/python/multi_usrp/multi_usrp_oscope.py b/gnuradio-examples/python/multi_usrp/multi_usrp_oscope.py deleted file mode 100755 index 512b125a4..000000000 --- a/gnuradio-examples/python/multi_usrp/multi_usrp_oscope.py +++ /dev/null @@ -1,343 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2004,2005,2006 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. -# - -# print "Loading revised usrp_oscope with additional options for scopesink..." - -from gnuradio import gr, gru -from gnuradio import usrp -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from gnuradio.wxgui import stdgui, fftsink, waterfallsink, scopesink, form, slider -from optparse import OptionParser -import wx -import sys - -import time -from gnuradio import usrp_multi - - -def pick_subdevice(u): - """ - The user didn't specify a subdevice on the command line. - If there's a daughterboard on A, select A. - If there's a daughterboard on B, select B. - Otherwise, select A. - """ - if u.db(0, 0).dbid() >= 0: # dbid is < 0 if there's no d'board or a problem - return (0, 0) - if u.db(0, 0).dbid() >= 0: - return (1, 0) - return (0, 0) - - -class 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=None, - help="select USRP Rx side A or B (default=first one with a daughterboard)") - parser.add_option("-d", "--decim", type="int", default=128, - 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("-g", "--gain", type="eng_float", default=None, - help="set gain in dB (default is midpoint)") - #align interval is default not yet enabled in gr.align_on_samplenumbers_ss - #parser.add_option("-a", "--align_interval", type="int", default=-1, - # help="Align master and slave every so much samples.") - - # width 8 does not work yet with multi_usrp because it interferes with the 32 bit samplecounter - #parser.add_option("-8", "--width-8", action="store_true", default=False, - # help="Enable 8-bit samples across USB") - parser.add_option("-m", "--mux", type="intx", default=None, - help="set fpga FR_RX_MUX register to MUX") - parser.add_option("-n", "--frame-decim", type="int", default=1, - help="set oscope frame decimation factor to n [default=1]") - parser.add_option("-N", "--nchan", type="int", default=2, - help="set nchannels to NCHAN") - parser.add_option("-q", "--show-q", action="store_true", default=False, - help="show the q value of the complex samples") - parser.add_option("-s", "--show-counters", action="store_true", default=False, - help="show the counters") - parser.add_option("-v", "--v-scale", type="eng_float", default=1000, - help="set oscope initial V/div to SCALE [default=%default]") - parser.add_option("-t", "--t-scale", type="eng_float", default=49e-6, - help="set oscope initial s/div to SCALE [default=50us]") - parser.add_option("-x", "--master-serialno", type="string", default=None, - help="Serial_no of the usrp which should be the MASTER (default= select any)") - (options, args) = parser.parse_args() - if len(args) != 0: - parser.print_help() - sys.exit(1) - - self.show_debug_info = True - - # build the graph - - #self.u = usrp.source_c(which=options.which_usrp,decim_rate=options.decim) - if (options.mux is None) | (4==options.nchan): - init_mux=None #use default mux which is 0x10321032 - else: - init_mux=options.mux - - init_gain=0.0 - init_freq=0.0 - init_align_interval=-1 - - self.multi=usrp_multi.multi_source_align( self, options.master_serialno, options.decim, - options.nchan, init_gain, init_freq, init_mux, init_align_interval) - self.um=self.multi.get_master_usrp() - self.us=self.multi.get_slave_usrp() - - if options.rx_subdev_spec is None: - options.rx_subdev_spec = pick_subdevice(self.um) - if (options.mux==None) and (options.nchan!=4): - mux=usrp.determine_rx_mux_value(self.um, options.rx_subdev_spec) - mux= (mux<<8 & 0xffffffff) | (mux & 0xff) - self.um.set_mux(mux) - self.us.set_mux(mux) - - # width 8 does not work yet with multi_usrp because it interferes with the 32 bit samplecounter - #if options.width_8: - # width = 8 - # shift = 8 - # format = self.um.make_format(width, shift) - # r = self.um.set_format(format) - # r = self.us.set_format(format) - - # determine the daughterboard subdevice of the first channel we're using - self.subdevm = usrp.selected_subdev(self.um, options.rx_subdev_spec) - self.subdevs = usrp.selected_subdev(self.us, options.rx_subdev_spec) - - input_rate = self.um.adc_freq() / self.um.decim_rate() - - self.scope = scopesink.scope_sink_f(self, panel, sample_rate=input_rate, - frame_decim=options.frame_decim, - v_scale=options.v_scale, - t_scale=options.t_scale) - self.sink_count=0 - self.add_to_scope((self.multi.get_master_source_c(),1),options.show_q) - self.add_to_scope((self.multi.get_slave_source_c(),1),options.show_q) - if 4==options.nchan: - self.add_to_scope((self.multi.get_master_source_c(),2),options.show_q) - self.add_to_scope((self.multi.get_slave_source_c(),2),options.show_q) - - if options.show_counters: - self.add_to_scope((self.multi.get_master_source_c(),0),options.show_q) - self.add_to_scope((self.multi.get_slave_source_c(),0),options.show_q) - - self._build_gui(vbox) - - # set initial values - - if options.gain is None: - # if no gain was specified, use the mid-point in dB - g = self.subdevm.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.subdevm.freq_range() - options.freq = float(r[0]+r[1])/2 - - self.set_gain(options.gain) - - if self.show_debug_info: - self.myform['decim'].set_value(self.um.decim_rate()) - self.myform['fs@usb'].set_value(self.um.adc_freq() / self.um.decim_rate()) - self.myform['dbname'].set_value(self.subdevm.name()) - self.myform['baseband'].set_value(0) - self.myform['ddc'].set_value(0) - - if not(self.set_freq(options.freq)): - self._set_status_msg("Failed to set initial frequency") - - self.multi.print_db_info() - self.unsynced=True - frame.Bind(wx.EVT_IDLE, self.onIdle) - - def add_to_scope(self,source_c,show_q): - c2f= gr.complex_to_float () - self.connect(source_c, c2f) - self.connect((c2f,0), (self.scope,self.sink_count)) - self.sink_count=self.sink_count+1 - if show_q: - self.connect((c2f,1), (self.scope,self.sink_count)) - self.sink_count=self.sink_count+1 - - - def _set_status_msg(self, msg): - self.frame.GetStatusBar().SetStatusText(msg, 0) - - def _build_gui(self, vbox): - - def _form_set_freq(kv): - return self.set_freq(kv['freq']) - - vbox.Add(self.scope.win, 10, wx.EXPAND) - - # add control area at the bottom - self.myform = myform = form.form() - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add((5,0), 0, 0) - myform['freq'] = form.float_field( - parent=self.panel, sizer=hbox, label="Center freq", weight=1, - callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg)) - - hbox.Add((5,0), 0, 0) - g = self.subdevm.gain_range() - myform['gain'] = form.slider_field(parent=self.panel, sizer=hbox, label="Gain", - weight=3, - min=int(g[0]), max=int(g[1]), - callback=self.set_gain) - - hbox.Add((5,0), 0, 0) - buttonSync = form.button_with_callback(parent=self.panel, label='sync',callback=self.sync_usrps) - hbox.Add(buttonSync,0,wx.EXPAND) - - hbox.Add((5,0), 0, 0) - vbox.Add(hbox, 0, wx.EXPAND) - - self._build_subpanel(vbox) - - def _build_subpanel(self, vbox_arg): - # build a secondary information panel (sometimes hidden) - - # FIXME figure out how to have this be a subpanel that is always - # created, but has its visibility controlled by foo.Show(True/False) - - if not(self.show_debug_info): - return - - panel = self.panel - vbox = vbox_arg - myform = self.myform - - #panel = wx.Panel(self.panel, -1) - #vbox = wx.BoxSizer(wx.VERTICAL) - - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add((5,0), 0) - myform['decim'] = form.static_float_field( - parent=panel, sizer=hbox, label="Decim") - - hbox.Add((5,0), 1) - myform['fs@usb'] = form.static_float_field( - parent=panel, sizer=hbox, label="Fs@USB") - - hbox.Add((5,0), 1) - myform['dbname'] = form.static_text_field( - parent=panel, sizer=hbox) - - hbox.Add((5,0), 1) - myform['baseband'] = form.static_float_field( - parent=panel, sizer=hbox, label="Analog BB") - - hbox.Add((5,0), 1) - myform['ddc'] = form.static_float_field( - parent=panel, sizer=hbox, label="DDC") - - hbox.Add((5,0), 0) - vbox.Add(hbox, 0, wx.EXPAND) - - - def set_freq(self, target_freq, sync=True): - """ - Set the center frequency we're interested in for all channels, - on all rx daughterboards on MASTER and SLAVE. - - @param target_freq: frequency in Hz - @param sync: sync the usrps after setting the freqs (this will clear any phase differences in the DDCS) - @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital down converter. - """ - result,r1,r2,r3,r4 = self.multi.tune_all_rx(target_freq) - if sync: - self.sync_usrps() #sync master and slave and clear any DDC phase differences - if r1: - self.myform['freq'].set_value(target_freq) # update displayed value - if self.show_debug_info: - self.myform['baseband'].set_value(r1.baseband_freq) - self.myform['ddc'].set_value(r1.dxc_freq) - return result - - def set_freq_chan0(self, target_freq, sync=True): - """ - Set the center frequency we're interested in for rx chan 0 only on MASTER and SLAVE. - - @param target_freq: frequency in Hz - @param sync: sync the usrps after setting the freqs (this will clear any phase differences in the DDCS) - @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital down converter. - """ - rm = usrp.tune(self.um, 0, self.subdevm, target_freq) - rs = usrp.tune(self.us, 0, self.subdevs, target_freq) - r=rm - if sync: - self.sync_usrps() #sync master and slave and clear any DDC phase differences - if r: - self.myform['freq'].set_value(target_freq) # update displayed value - if self.show_debug_info: - self.myform['baseband'].set_value(r.baseband_freq) - self.myform['ddc'].set_value(r.dxc_freq) - return True - - return False - - def set_gain(self, gain): - self.myform['gain'].set_value(gain) # update displayed value - self.multi.set_gain_all_rx(gain) - - def set_gain_chan0(self, gain): - self.myform['gain'].set_value(gain) # update displayed value - self.subdevm.set_gain(gain) - self.subdevs.set_gain(gain) - - def onIdle(self,evt): - if self.unsynced: - time.sleep(0.5) - self.unsynced=True - self.multi.sync() - self.unsynced=False - #print 'synced' - - def sync_usrps(self): - self.multi.sync() - -def main (): - app = stdgui.stdapp(app_flow_graph, "MULTI_USRP O'scope", nstatus=1) - app.MainLoop() - -if __name__ == '__main__': - main () diff --git a/gnuradio-examples/python/multi_usrp/multi_usrp_rx_cfile.py b/gnuradio-examples/python/multi_usrp/multi_usrp_rx_cfile.py deleted file mode 100755 index ca0ec97c2..000000000 --- a/gnuradio-examples/python/multi_usrp/multi_usrp_rx_cfile.py +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env python - -""" -Read samples 2 from two linked synchronised USRP's and write to file formatted as binary -single-precision complex values. -Make sure you read README on how to link the two usrps - -""" - -from gnuradio import gr, eng_notation -from gnuradio import audio -from gnuradio import usrp -from gnuradio.eng_option import eng_option -from optparse import OptionParser -import sys - -import time -from gnuradio import usrp_multi - -class my_top_block(gr.top_block): - - def __init__(self): - gr.top_block.__init__(self) - - usage="%prog: [options] output_filename" - parser = OptionParser(option_class=eng_option, usage=usage) - 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=128, - help="set selfpa decimation rate to DECIM [default=%default]") - parser.add_option("-f", "--freq", type="eng_float", default=0.0, - help="set frequency to FREQ", metavar="FREQ") - parser.add_option("-g", "--gain", type="eng_float", default=None, - help="set gain in dB (default is midpoint)") - parser.add_option("-n", "--nchan", type="intx", default=2, - help="set nchannels to NCHAN") - parser.add_option("-N", "--nsamples", type="eng_float", default=None, - help="number of samples to collect [default=+inf]") - parser.add_option ("-o", "--output-file-m", default="usrp_rx_m.dat", - help="write master data to FILE", metavar="FILE") - parser.add_option ("--output-file-m2", default="usrp_rx_m2.dat", - help="write master data from second channel to FILE", metavar="FILE") - parser.add_option ("-p", "--output-file-s", default="usrp_rx_s.dat", - help="write slave data to FILE", metavar="FILE") - parser.add_option ("--output-file-s2", default="usrp_rx_s2.dat", - help="write slave data from second channel to FILE", metavar="FILE") - parser.add_option("-x", "--master-serialno", type="string", default=None, - help="Serial_no of the usrp which should be the MASTER (default= select any)") - (options, args) = parser.parse_args () - if len(args) != 0: - parser.print_help() - raise SystemExit, 1 - - if options.freq is None: - parser.print_help() - sys.stderr.write('You must specify the frequency with -f FREQ\n'); - raise SystemExit, 1 - - # build the graph - self.multi=usrp_multi.multi_source_align( fg=self, master_serialno=options.master_serialno, decim=options.decim, - nchan=options.nchan ) - self.um=self.multi.get_master_usrp() - self.us=self.multi.get_slave_usrp() - - dst_m=gr.file_sink (gr.sizeof_gr_complex, options.output_file_m) - dst_s=gr.file_sink (gr.sizeof_gr_complex, options.output_file_s) - if options.nsamples is None: - self.connect((self.multi.get_master_source_c(),1),dst_m) - self.connect((self.multi.get_slave_source_c(),1),dst_s) - else: - head_m = gr.head(gr.sizeof_gr_complex, int(options.nsamples)) - head_s = gr.head(gr.sizeof_gr_complex, int(options.nsamples)) - self.connect((self.multi.get_master_source_c(),1),head_m,dst_m) - self.connect((self.multi.get_slave_source_c(),1),head_s,dst_s) - - if(4==options.nchan): - dst_m2=gr.file_sink (gr.sizeof_gr_complex, options.output_file_m2) - dst_s2=gr.file_sink (gr.sizeof_gr_complex, options.output_file_s2) - if options.nsamples is None: - self.connect((self.multi.get_master_source_c(),2),dst_m2) - self.connect((self.multi.get_slave_source_c(),2),dst_s2) - else: - head_m2 = gr.head(gr.sizeof_gr_complex, int(options.nsamples)) - head_s2 = gr.head(gr.sizeof_gr_complex, int(options.nsamples)) - self.connect((self.multi.get_master_source_c(),2),head_m2,dst_m2) - self.connect((self.multi.get_slave_source_c(),2),head_s2,dst_s2) - - if options.rx_subdev_spec is None: - options.rx_subdev_spec = usrp.pick_rx_subdevice(self.um) - - if (options.nchan!=4): - mux=usrp.determine_rx_mux_value(self.um, options.rx_subdev_spec) - mux= (mux<<8 & 0xffffffff) | (mux & 0xff) - self.um.set_mux(mux) - self.us.set_mux(mux) - - # determine the daughterboard subdevice we're using - self.subdevm = usrp.selected_subdev(self.um, options.rx_subdev_spec) - self.subdevs = usrp.selected_subdev(self.us, options.rx_subdev_spec) - print "Using MASTER RX d'board %s" % (self.subdevm.side_and_name(),) - print "Using SLAVE RX d'board %s" % (self.subdevs.side_and_name(),) - input_rate = self.um.adc_freq() / self.um.decim_rate() - print "USB sample rate %s" % (eng_notation.num_to_str(input_rate)) - - if options.gain is None: - # if no gain was specified, use the mid-point in dB - g = self.subdevm.gain_range() - options.gain = float(g[0]+g[1])/2 - - self.multi.set_gain_all_rx(options.gain) - result,r1,r2,r3,r4 = self.multi.tune_all_rx(options.freq) - if not result: - sys.stderr.write('Failed to set frequency\n') - raise SystemExit, 1 - - def sync_usrps(self): - self.multi.sync() - - -if __name__ == '__main__': - tb=my_top_block() - tb.start() - #time.sleep(0.5) - tb.sync_usrps() - raw_input ('Press Enter to quit: ') - tb.stop() - #try: - # fg.start() - # fg.sync_usrps() - #except KeyboardInterrupt: - # pass diff --git a/gnuradio-pkg_chk.conf b/gnuradio-pkg_chk.conf index 7f81101f4..ab53c1522 100644 --- a/gnuradio-pkg_chk.conf +++ b/gnuradio-pkg_chk.conf @@ -73,7 +73,3 @@ devel/libusb ## GUI x11/py-wxWidgets - -## gr-radio-astronomy - -math/py-ephem diff --git a/gr-atsc/src/python/README b/gr-atsc/src/python/README index abe0937b5..6c23b46fd 100644 --- a/gr-atsc/src/python/README +++ b/gr-atsc/src/python/README @@ -1,13 +1,13 @@ Decoding ATSC using 19.2MSps rate over 5 processes -------------------------------------------------- -1) Verify signal, adjust antenna and find best gain setting using usrp_fft.py, -station frequency from the fcc video database, and decimation of 10. +1) Verify signal, adjust antenna and find best gain setting using uhd_fft.py, +station frequency from the fcc video database, and sample rate to 6.4e6. 2) Capture data - adjust gain (-g) frequency (-f) and which side the tvrx is on to fit your local setup: -usrp_rx_cfile.py -s -R B -d 10 -g 65 -f 503e6 atsc_data_6-4m_complex +uhd_rx_cfile.py -s --samp-rate=6.4e6 -g 65 -f 503e6 atsc_data_6-4m_complex You probably still need fast disks to take the data, like a raid-0 set of striped sata drives. Make sure there are no or very few Ou overruns. Saving diff --git a/gr-atsc/src/python/interp.py b/gr-atsc/src/python/interp.py index ad69c6b34..b17b3a312 100755 --- a/gr-atsc/src/python/interp.py +++ b/gr-atsc/src/python/interp.py @@ -22,8 +22,7 @@ # This module starts the atsc processing chain taking the captured # off-air signal created with: # -# usrp_rx_cfile.py -R <side with tuner, a or b> -# -d 10 set decimation to get signal at 6.4e6 rate +# uhd_rx_cfile.py --samp-rate=6.4e6 # -f <center of tv signal channel freq> # -g <appropriate gain for best signal / noise> # diff --git a/gr-atsc/src/python/interp_short.py b/gr-atsc/src/python/interp_short.py index 11b169b27..732ca831d 100755 --- a/gr-atsc/src/python/interp_short.py +++ b/gr-atsc/src/python/interp_short.py @@ -22,8 +22,7 @@ # This module starts the atsc processing chain taking the captured # off-air signal created with: # -# usrp_rx_cfile.py -R <side with tuner, a or b> -# -d 10 set decimation to get signal at 6.4e6 rate +# uhd_rx_cfile.py --samp-rate=6.4e6 # -f <center of tv signal channel freq> # -g <appropriate gain for best signal / noise> # -s output shorts diff --git a/gr-digital/examples/README b/gr-digital/examples/narrowband/README index 1c50ad69b..1c50ad69b 100644 --- a/gr-digital/examples/README +++ b/gr-digital/examples/narrowband/README diff --git a/gr-digital/examples/narrowband/benchmark_rx.py b/gr-digital/examples/narrowband/benchmark_rx.py index 65aac3638..32c3222ae 100755 --- a/gr-digital/examples/narrowband/benchmark_rx.py +++ b/gr-digital/examples/narrowband/benchmark_rx.py @@ -44,7 +44,11 @@ class my_top_block(gr.top_block): gr.top_block.__init__(self) if(options.rx_freq is not None): - self.source = uhd_receiver(options.address, options.bitrate, + # Work-around to get the modulation's bits_per_symbol + args = demodulator.extract_kwargs_from_options(options) + symbol_rate = options.bitrate / demodulator(**args).bits_per_symbol() + + self.source = uhd_receiver(options.args, symbol_rate, options.samples_per_symbol, options.rx_freq, options.rx_gain, options.antenna, options.verbose) diff --git a/gr-digital/examples/narrowband/benchmark_tx.py b/gr-digital/examples/narrowband/benchmark_tx.py index 1fd881981..25ed355da 100755 --- a/gr-digital/examples/narrowband/benchmark_tx.py +++ b/gr-digital/examples/narrowband/benchmark_tx.py @@ -43,7 +43,11 @@ class my_top_block(gr.top_block): gr.top_block.__init__(self) if(options.tx_freq is not None): - self.sink = uhd_transmitter(options.address, options.bitrate, + # Work-around to get the modulation's bits_per_symbol + args = modulator.extract_kwargs_from_options(options) + symbol_rate = options.bitrate / modulator(**args).bits_per_symbol() + + self.sink = uhd_transmitter(options.args, symbol_rate, options.samples_per_symbol, options.tx_freq, options.tx_gain, options.antenna, options.verbose) diff --git a/gr-digital/examples/narrowband/digital_bert_rx.py b/gr-digital/examples/narrowband/digital_bert_rx.py index 9878f55e1..28331310d 100755 --- a/gr-digital/examples/narrowband/digital_bert_rx.py +++ b/gr-digital/examples/narrowband/digital_bert_rx.py @@ -113,7 +113,7 @@ class rx_psk_block(gr.top_block): self._demodulator = self._demodulator_class(**demod_kwargs) if(options.rx_freq is not None): - self._source = uhd_receiver(options.address, options.bitrate, + self._source = uhd_receiver(options.args, options.bitrate, options.samples_per_symbol, options.rx_freq, options.rx_gain, options.antenna, options.verbose) diff --git a/gr-digital/examples/narrowband/digital_bert_tx.py b/gr-digital/examples/narrowband/digital_bert_tx.py index 96cb338fe..46f4f9097 100755 --- a/gr-digital/examples/narrowband/digital_bert_tx.py +++ b/gr-digital/examples/narrowband/digital_bert_tx.py @@ -67,7 +67,7 @@ class tx_psk_block(gr.top_block): self._modulator = self._modulator_class(**mod_kwargs) if(options.tx_freq is not None): - self._sink = uhd_transmitter(options.address, options.bitrate, + self._sink = uhd_transmitter(options.args, options.bitrate, options.samples_per_symbol, options.tx_freq, options.tx_gain, options.antenna, options.verbose) diff --git a/gr-digital/examples/narrowband/rx_voice.py b/gr-digital/examples/narrowband/rx_voice.py index 42d7b893b..100caff8e 100755 --- a/gr-digital/examples/narrowband/rx_voice.py +++ b/gr-digital/examples/narrowband/rx_voice.py @@ -66,7 +66,7 @@ class my_top_block(gr.top_block): self.audio_tx = audio_tx(options.audio_output) if(options.rx_freq is not None): - self.source = uhd_receiver(options.address, options.bitrate, + self.source = uhd_receiver(options.args, options.bitrate, options.samples_per_symbol, options.rx_freq, options.rx_gain, options.antenna, options.verbose) diff --git a/gr-digital/examples/narrowband/tunnel.py b/gr-digital/examples/narrowband/tunnel.py index 7f40bb1c3..7414a7227 100755 --- a/gr-digital/examples/narrowband/tunnel.py +++ b/gr-digital/examples/narrowband/tunnel.py @@ -92,12 +92,16 @@ class my_top_block(gr.top_block): gr.top_block.__init__(self) - self.source = uhd_receiver(options.address, options.bitrate, + # Get the modulation's bits_per_symbol + args = mod_class.extract_kwargs_from_options(options) + symbol_rate = options.bitrate / mod_class(**args).bits_per_symbol() + + self.source = uhd_receiver(options.args, symbol_rate, options.samples_per_symbol, options.rx_freq, options.rx_gain, options.antenna, options.verbose) - self.sink = uhd_transmitter(options.address, options.bitrate, + self.sink = uhd_transmitter(options.args, symbol_rate, options.samples_per_symbol, options.tx_freq, options.tx_gain, options.antenna, options.verbose) diff --git a/gr-digital/examples/narrowband/uhd_interface.py b/gr-digital/examples/narrowband/uhd_interface.py index 8420f3eec..a0be516ec 100644 --- a/gr-digital/examples/narrowband/uhd_interface.py +++ b/gr-digital/examples/narrowband/uhd_interface.py @@ -42,36 +42,36 @@ def add_freq_option(parser): metavar="FREQ") class uhd_interface: - def __init__(self, istx, address, bitrate, sps, freq=None, + def __init__(self, istx, args, sym_rate, sps, freq=None, gain=None, antenna=None): if(istx): - self.u = uhd.usrp_sink(device_addr=address, + self.u = uhd.usrp_sink(device_addr=args, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=1) else: - self.u = uhd.usrp_source(device_addr=address, + self.u = uhd.usrp_source(device_addr=args, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=1) - self._addr = address + self._args = args self._ant = antenna self._gain = self.set_gain(gain) self._freq = self.set_freq(freq) - self._rate, self._sps = self.set_sample_rate(bitrate, sps) + self._rate, self._sps = self.set_sample_rate(sym_rate, sps) if(antenna): self.u.set_antenna(antenna, 0) - def set_sample_rate(self, bitrate, req_sps): + def set_sample_rate(self, sym_rate, req_sps): start_sps = req_sps while(True): - asked_samp_rate = bitrate * req_sps + asked_samp_rate = sym_rate * req_sps self.u.set_samp_rate(asked_samp_rate) actual_samp_rate = self.u.get_samp_rate() - sps = actual_samp_rate/bitrate + sps = actual_samp_rate/sym_rate if(sps < 2): req_sps +=1 else: @@ -79,7 +79,7 @@ class uhd_interface: break if(sps != req_sps): - print "\nBit Rate: %f" % (bitrate) + print "\nSymbol Rate: %f" % (sym_rate) print "Requested sps: %f" % (start_sps) print "Given sample rate: %f" % (actual_samp_rate) print "Actual sps for rate: %f" % (actual_sps) @@ -124,14 +124,14 @@ class uhd_interface: #-------------------------------------------------------------------# class uhd_transmitter(uhd_interface, gr.hier_block2): - def __init__(self, address, bitrate, sps, freq=None, gain=None, + def __init__(self, args, sym_rate, sps, freq=None, gain=None, antenna=None, verbose=False): gr.hier_block2.__init__(self, "uhd_transmitter", gr.io_signature(1,1,gr.sizeof_gr_complex), gr.io_signature(0,0,0)) # Set up the UHD interface as a transmitter - uhd_interface.__init__(self, True, address, bitrate, sps, + uhd_interface.__init__(self, True, args, sym_rate, sps, freq, gain, antenna) self.connect(self, self.u) @@ -141,8 +141,8 @@ class uhd_transmitter(uhd_interface, gr.hier_block2): def add_options(parser): add_freq_option(parser) - parser.add_option("-a", "--address", type="string", default="addr=192.168.10.2", - help="Address of UHD device, [default=%default]") + parser.add_option("-a", "--args", type="string", default="", + help="UHD device address args [default=%default]") parser.add_option("-A", "--antenna", type="string", default=None, help="select Rx Antenna where appropriate") parser.add_option("", "--tx-freq", type="eng_float", default=None, @@ -160,7 +160,7 @@ class uhd_transmitter(uhd_interface, gr.hier_block2): Prints information about the UHD transmitter """ print "\nUHD Transmitter:" - print "Address: %s" % (self._addr) + print "Args: %s" % (self._args) print "Freq: %sHz" % (eng_notation.num_to_str(self._freq)) print "Gain: %f dB" % (self._gain) print "Sample Rate: %ssps" % (eng_notation.num_to_str(self._rate)) @@ -174,14 +174,14 @@ class uhd_transmitter(uhd_interface, gr.hier_block2): class uhd_receiver(uhd_interface, gr.hier_block2): - def __init__(self, address, bitrate, sps, freq=None, gain=None, + def __init__(self, args, sym_rate, sps, freq=None, gain=None, antenna=None, verbose=False): gr.hier_block2.__init__(self, "uhd_receiver", gr.io_signature(0,0,0), gr.io_signature(1,1,gr.sizeof_gr_complex)) # Set up the UHD interface as a receiver - uhd_interface.__init__(self, False, address, bitrate, sps, + uhd_interface.__init__(self, False, args, sym_rate, sps, freq, gain, antenna) self.connect(self.u, self) @@ -191,8 +191,8 @@ class uhd_receiver(uhd_interface, gr.hier_block2): def add_options(parser): add_freq_option(parser) - parser.add_option("-a", "--address", type="string", default="addr=192.168.10.2", - help="Address of UHD device, [default=%default]") + parser.add_option("-a", "--args", type="string", default="", + help="UHD device address args [default=%default]") parser.add_option("-A", "--antenna", type="string", default=None, help="select Rx Antenna where appropriate") parser.add_option("", "--rx-freq", type="eng_float", default=None, @@ -211,7 +211,7 @@ class uhd_receiver(uhd_interface, gr.hier_block2): Prints information about the UHD transmitter """ print "\nUHD Receiver:" - print "Address: %s" % (self._addr) + print "UHD Args: %s" % (self._args) print "Freq: %sHz" % (eng_notation.num_to_str(self._freq)) print "Gain: %f dB" % (self._gain) print "Sample Rate: %ssps" % (eng_notation.num_to_str(self._rate)) diff --git a/gr-digital/examples/ofdm/benchmark_rx.py b/gr-digital/examples/ofdm/benchmark_rx.py index f2ed3b8ff..a386a80e4 100755 --- a/gr-digital/examples/ofdm/benchmark_rx.py +++ b/gr-digital/examples/ofdm/benchmark_rx.py @@ -38,7 +38,7 @@ class my_top_block(gr.top_block): gr.top_block.__init__(self) if(options.rx_freq is not None): - self.source = uhd_receiver(options.address, + self.source = uhd_receiver(options.args, options.bandwidth, options.rx_freq, options.rx_gain, options.antenna, options.verbose) diff --git a/gr-digital/examples/ofdm/benchmark_tx.py b/gr-digital/examples/ofdm/benchmark_tx.py index ad3609b52..dd0c69b57 100755 --- a/gr-digital/examples/ofdm/benchmark_tx.py +++ b/gr-digital/examples/ofdm/benchmark_tx.py @@ -37,7 +37,7 @@ class my_top_block(gr.top_block): gr.top_block.__init__(self) if(options.tx_freq is not None): - self.sink = uhd_transmitter(options.address, + self.sink = uhd_transmitter(options.args, options.bandwidth, options.tx_freq, options.tx_gain, options.antenna, options.verbose) diff --git a/gr-digital/examples/ofdm/tunnel.py b/gr-digital/examples/ofdm/tunnel.py index 74f2667fa..dc862fbec 100755 --- a/gr-digital/examples/ofdm/tunnel.py +++ b/gr-digital/examples/ofdm/tunnel.py @@ -87,12 +87,12 @@ class my_top_block(gr.top_block): def __init__(self, callback, options): gr.top_block.__init__(self) - self.source = uhd_receiver(options.address, + self.source = uhd_receiver(options.args, options.bandwidth, options.rx_freq, options.rx_gain, options.antenna, options.verbose) - self.sink = uhd_transmitter(options.address, + self.sink = uhd_transmitter(options.args, options.bandwidth, options.tx_freq, options.tx_gain, options.antenna, options.verbose) diff --git a/gr-digital/examples/ofdm/uhd_interface.py b/gr-digital/examples/ofdm/uhd_interface.py index d03bd7f46..cd2d3152d 100644 --- a/gr-digital/examples/ofdm/uhd_interface.py +++ b/gr-digital/examples/ofdm/uhd_interface.py @@ -42,19 +42,19 @@ def add_freq_option(parser): metavar="FREQ") class uhd_interface: - def __init__(self, istx, address, bandwidth, freq=None, + def __init__(self, istx, args, bandwidth, freq=None, gain=None, antenna=None): if(istx): - self.u = uhd.usrp_sink(device_addr=address, + self.u = uhd.usrp_sink(device_addr=args, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=1) else: - self.u = uhd.usrp_source(device_addr=address, + self.u = uhd.usrp_source(device_addr=args, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=1) - self._addr = address + self._args = args self._ant = antenna self._gain = self.set_gain(gain) self._freq = self.set_freq(freq) @@ -104,14 +104,14 @@ class uhd_interface: #-------------------------------------------------------------------# class uhd_transmitter(uhd_interface, gr.hier_block2): - def __init__(self, address, bandwidth, freq=None, gain=None, + def __init__(self, args, bandwidth, freq=None, gain=None, antenna=None, verbose=False): gr.hier_block2.__init__(self, "uhd_transmitter", gr.io_signature(1,1,gr.sizeof_gr_complex), gr.io_signature(0,0,0)) # Set up the UHD interface as a transmitter - uhd_interface.__init__(self, True, address, bandwidth, + uhd_interface.__init__(self, True, args, bandwidth, freq, gain, antenna) self.connect(self, self.u) @@ -121,8 +121,8 @@ class uhd_transmitter(uhd_interface, gr.hier_block2): def add_options(parser): add_freq_option(parser) - parser.add_option("-a", "--address", type="string", default="addr=192.168.10.2", - help="Address of UHD device, [default=%default]") + parser.add_option("-a", "--args", type="string", default="", + help="UHD device address args [default=%default]") parser.add_option("-A", "--antenna", type="string", default=None, help="select Rx Antenna where appropriate") parser.add_option("", "--tx-freq", type="eng_float", default=None, @@ -140,7 +140,7 @@ class uhd_transmitter(uhd_interface, gr.hier_block2): Prints information about the UHD transmitter """ print "\nUHD Transmitter:" - print "Address: %s" % (self._addr) + print "UHD Args: %s" % (self._args) print "Freq: %sHz" % (eng_notation.num_to_str(self._freq)) print "Gain: %f dB" % (self._gain) print "Sample Rate: %ssps" % (eng_notation.num_to_str(self._rate)) @@ -154,14 +154,14 @@ class uhd_transmitter(uhd_interface, gr.hier_block2): class uhd_receiver(uhd_interface, gr.hier_block2): - def __init__(self, address, bandwidth, freq=None, gain=None, + def __init__(self, args, bandwidth, freq=None, gain=None, antenna=None, verbose=False): gr.hier_block2.__init__(self, "uhd_receiver", gr.io_signature(0,0,0), gr.io_signature(1,1,gr.sizeof_gr_complex)) # Set up the UHD interface as a receiver - uhd_interface.__init__(self, False, address, bandwidth, + uhd_interface.__init__(self, False, args, bandwidth, freq, gain, antenna) self.connect(self.u, self) @@ -171,8 +171,8 @@ class uhd_receiver(uhd_interface, gr.hier_block2): def add_options(parser): add_freq_option(parser) - parser.add_option("-a", "--address", type="string", default="addr=192.168.10.2", - help="Address of UHD device, [default=%default]") + parser.add_option("-a", "--args", type="string", default="", + help="UHD device address args [default=%default]") parser.add_option("-A", "--antenna", type="string", default=None, help="select Rx Antenna where appropriate") parser.add_option("", "--rx-freq", type="eng_float", default=None, @@ -191,7 +191,7 @@ class uhd_receiver(uhd_interface, gr.hier_block2): Prints information about the UHD transmitter """ print "\nUHD Receiver:" - print "Address: %s" % (self._addr) + print "UHD Args: %s" % (self._args) print "Freq: %sHz" % (eng_notation.num_to_str(self._freq)) print "Gain: %f dB" % (self._gain) print "Sample Rate: %ssps" % (eng_notation.num_to_str(self._rate)) diff --git a/gr-howto-write-a-block/config/Makefile.am b/gr-howto-write-a-block/config/Makefile.am index aaaf0db7c..7b7e5812e 100644 --- a/gr-howto-write-a-block/config/Makefile.am +++ b/gr-howto-write-a-block/config/Makefile.am @@ -46,7 +46,6 @@ m4macros = \ gr_check_createfilemapping.m4 \ gr_check_mc4020.m4 \ gr_check_shm_open.m4 \ - gr_check_usrp.m4 \ gr_doxygen.m4 \ gr_fortran.m4 \ gr_git.m4 \ @@ -72,10 +71,7 @@ m4macros = \ lf_x11.m4 \ mkstemp.m4 \ onceonly.m4 \ - pkg.m4 \ - usrp_fusb_tech.m4 \ - usrp_libusb.m4 \ - usrp_sdcc.m4 + pkg.m4 # Don't install m4 macros anymore diff --git a/gr-pager/apps/usrp_flex.py b/gr-pager/apps/usrp_flex.py index f8d9d25b1..7c90d9296 100755 --- a/gr-pager/apps/usrp_flex.py +++ b/gr-pager/apps/usrp_flex.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2006,2007,2009 Free Software Foundation, Inc. +# Copyright 2006,2007,2009,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -20,32 +20,11 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr, gru, usrp, optfir, eng_notation, pager +from gnuradio import gr, gru, uhd, optfir, eng_notation, pager from gnuradio.eng_option import eng_option from optparse import OptionParser import time, os, sys -""" -This example application demonstrates receiving and demodulating the -FLEX pager protocol. - -The following are required command line parameters: - --f FREQ USRP receive frequency - -The following are optional command line parameters: - --R SUBDEV Daughter board specification, defaults to first found --F FILE Read samples from a file instead of USRP. --c FREQ Calibration offset. Gets added to receive frequency. - Defaults to 0.0 Hz. --g GAIN Daughterboard gain setting. Defaults to mid-range. --l Log flow graph to files (LOTS of data) --v Verbose output - -Once the program is running, ctrl-break (Ctrl-C) stops operation. -""" - class app_top_block(gr.top_block): def __init__(self, options, queue): gr.top_block.__init__(self, "usrp_flex") @@ -55,43 +34,46 @@ class app_top_block(gr.top_block): self.verbose = options.verbose if options.from_file is None: - # Set up USRP source with specified RX daughterboard - self.src = usrp.source_c() - if options.rx_subdev_spec == None: - options.rx_subdev_spec = usrp.pick_rx_subdevice(self.src) - self.subdev = usrp.selected_subdev(self.src, options.rx_subdev_spec) - self.src.set_mux(usrp.determine_rx_mux_value(self.src, options.rx_subdev_spec)) - - # Grab 250 KHz of spectrum (sample rate becomes 250 ksps complex) - self.src.set_decim_rate(256) - - # If no gain specified, set to midrange - if options.gain is None: - g = self.subdev.gain_range() - options.gain = (g[0]+g[1])/2.0 - self.subdev.set_gain(options.gain) - + # Set up USRP source + self.u = uhd.usrp_source(device_addr=options.address, + io_type=uhd.io_type.COMPLEX_FLOAT32, + num_channels=1) + + # Grab 250 KHz of spectrum + # (A UHD facility to get sample rate range and granularity would be useful) + self.u.set_samp_rate(250e3) + rate = self.u.get_samp_rate() + if rate != 250e3: + print "Unable to set required sample rate of 250 Ksps (got %f)" % rate + sys.exit(1) + # Tune daughterboard - actual_frequency = options.frequency+options.calibration - tune_result = usrp.tune(self.src, 0, self.subdev, actual_frequency) - if not tune_result: - sys.stderr.write("Failed to set center frequency to "+`actual_frequency`+"\n") + r = self.u.set_center_freq(options.freq+options.calibration, 0) + if not r: + frange = self.u.get_freq_range() + sys.stderr.write(("\nRequested frequency (%f) out or range [%f, %f]\n") % \ + (freq, frange.start(), frange.stop())) sys.exit(1) - if options.verbose: - print "Using RX daughterboard", self.subdev.side_and_name() - print "USRP gain is", options.gain - print "USRP tuned to", actual_frequency - + # if no gain was specified, use the mid-point in dB + if options.rx_gain is None: + grange = self.u.get_gain_range() + options.rx_gain = float(grange.start()+grange.stop())/2.0 + print "\nNo gain specified." + print "Setting gain to %f (from [%f, %f])" % \ + (options.rx_gain, grange.start(), grange.stop()) + + self.u.set_gain(options.rx_gain, 0) + else: # Use supplied file as source of samples - self.src = gr.file_source(gr.sizeof_gr_complex, options.from_file) + self.u = gr.file_source(gr.sizeof_gr_complex, options.from_file) if options.verbose: print "Reading samples from", options.from_file if options.log and not options.from_file: usrp_sink = gr.file_sink(gr.sizeof_gr_complex, 'usrp.dat') - self.connect(self.src, usrp_sink) + self.connect(self.u, usrp_sink) # Set up 22KHz-wide bandpass about center frequency. Decimate by 10 # to get channel rate of 25Ksps @@ -115,9 +97,9 @@ class app_top_block(gr.top_block): self.connect(self.chan, chan_sink) # FLEX protocol demodulator - self.flex = pager.flex_demod(queue, options.frequency, options.verbose, options.log) + self.flex = pager.flex_demod(queue, options.freq, options.verbose, options.log) - self.connect(self.src, self.chan, self.flex) + self.connect(self.u, self.chan, self.flex) def freq_offset(self): return self.flex.dc_offset()*1600 @@ -130,30 +112,42 @@ class app_top_block(gr.top_block): if self.verbose: print "Channel frequency offset (Hz):", int(self.offset) -def main(): + +def get_options(): parser = OptionParser(option_class=eng_option) - parser.add_option("-f", "--frequency", type="eng_float", default=None, - help="set receive frequency to Hz", metavar="Hz") - parser.add_option("-R", "--rx-subdev-spec", type="subdev", - help="select USRP Rx side A or B", metavar="SUBDEV") + + parser.add_option('-f', '--freq', type="eng_float", default=None, + help="Set receive frequency to FREQ [default=%default]", + metavar="FREQ") + parser.add_option("-a", "--address", type="string", default="addr=192.168.10.2", + help="Address of UHD device, [default=%default]") + parser.add_option("-A", "--antenna", type="string", default=None, + help="select Rx Antenna where appropriate") + parser.add_option("", "--rx-gain", type="eng_float", default=None, + help="set receive gain in dB (default is midpoint)") parser.add_option("-c", "--calibration", type="eng_float", default=0.0, help="set frequency offset to Hz", metavar="Hz") - parser.add_option("-g", "--gain", type="int", default=None, - help="set RF gain", metavar="dB") + parser.add_option("-v", "--verbose", action="store_true", default=False) parser.add_option("-l", "--log", action="store_true", default=False, help="log flowgraph to files (LOTS of data)") - parser.add_option("-v", "--verbose", action="store_true", default=False, - help="display debug output") parser.add_option("-F", "--from-file", default=None, help="read samples from file instead of USRP") + (options, args) = parser.parse_args() - if len(args) > 0 or (options.frequency == None and options.from_file == None): + if len(args) > 0: print "Run 'usrp_flex.py -h' for options." sys.exit(1) - if options.frequency == None: - options.frequency = 0.0 + if (options.freq is None): + sys.stderr.write("You must specify -f FREQ or --freq FREQ\n") + sys.exit(1) + + return (options, args) + +if __name__ == "__main__": + + (options, args) = get_options() # Flow graph emits pages into message queue queue = gr.msg_queue() @@ -167,6 +161,3 @@ def main(): runner.end() - -if __name__ == "__main__": - main() diff --git a/gr-pager/apps/usrp_flex_band.py b/gr-pager/apps/usrp_flex_band.py index 06c2488c0..8ea76c229 100755 --- a/gr-pager/apps/usrp_flex_band.py +++ b/gr-pager/apps/usrp_flex_band.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2006,2007,2009 Free Software Foundation, Inc. +# Copyright 2006,2007,2009,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -20,32 +20,52 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr, gru, usrp, optfir, eng_notation, blks2, pager +from gnuradio import gr, gru, uhd, optfir, eng_notation, blks2, pager from gnuradio.eng_option import eng_option from optparse import OptionParser +import sys class app_top_block(gr.top_block): def __init__(self, options, queue): gr.top_block.__init__(self, "usrp_flex_all") - self.subdev = None if options.from_file is not None: - self.src = gr.file_source(gr.sizeof_gr_complex, options.from_file) + self.u = gr.file_source(gr.sizeof_gr_complex, options.from_file) if options.verbose: print "Reading samples from file", options.from_file else: - self.src = usrp.source_c() - if options.rx_subdev_spec is None: - options.rx_subdev_spec = usrp.pick_rx_subdevice(self.src) - self.subdev = usrp.selected_subdev(self.src, options.rx_subdev_spec) - self.src.set_mux(usrp.determine_rx_mux_value(self.src, options.rx_subdev_spec)) - self.src.set_decim_rate(64) - frequency = options.frequency+options.calibration - result = usrp.tune(self.src, 0, self.subdev, frequency) - if options.verbose: - print "Using", self.subdev.name(), " for receiving." - print "Tuned USRP to", frequency + # Set up USRP source + self.u = uhd.usrp_source(device_addr=options.address, + io_type=uhd.io_type.COMPLEX_FLOAT32, + num_channels=1) + + # Grab 1 MHz of spectrum + # (A UHD facility to get sample rate range and granularity would be useful) + self.u.set_samp_rate(1e6) + rate = self.u.get_samp_rate() + if rate != 1e6: + print "Unable to set required sample rate of 1 Msps (got %f)" % rate + sys.exit(1) + # Tune daughterboard + r = self.u.set_center_freq(options.freq+options.calibration, 0) + if not r: + frange = self.u.get_freq_range() + sys.stderr.write(("\nRequested frequency (%f) out or range [%f, %f]\n") % \ + (freq, frange.start(), frange.stop())) + sys.exit(1) + + # if no gain was specified, use the mid-point in dB + if options.rx_gain is None: + grange = self.u.get_gain_range() + options.rx_gain = float(grange.start()+grange.stop())/2.0 + print "\nNo gain specified." + print "Setting gain to %f (from [%f, %f])" % \ + (options.rx_gain, grange.start(), grange.stop()) + + self.u.set_gain(options.rx_gain, 0) + + taps = gr.firdes.low_pass(1.0, 1.0, 1.0/40.0*0.4, @@ -56,43 +76,59 @@ class app_top_block(gr.top_block): print "Channel filter has", len(taps), "taps" bank = blks2.analysis_filterbank(40, taps) - self.connect(self.src, bank) + self.connect(self.u, bank) if options.log and options.from_file == None: src_sink = gr.file_sink(gr.sizeof_gr_complex, 'usrp.dat') - self.connect(self.src, src_sink) + self.connect(self.u, src_sink) for i in range(40): if i < 20: - freq = options.frequency+i*25e3 + freq = options.freq+i*25e3 else: - freq = options.frequency-0.5e6+(i-20)*25e3 + freq = options.freq-0.5e6+(i-20)*25e3 self.connect((bank, i), pager.flex_demod(queue, freq, options.verbose, options.log)) if options.log: self.connect((bank, i), gr.file_sink(gr.sizeof_gr_complex, 'chan_'+'%3.3f'%(freq/1e6)+'.dat')) -def main(): +def get_options(): parser = OptionParser(option_class=eng_option) - parser.add_option("-f", "--frequency", type="eng_float", default=929.5e6, - help="set receive center frequency to Hz", metavar="Hz") - parser.add_option("-R", "--rx-subdev-spec", type="subdev", - help="select USRP Rx side A or B (default=first daughterboard found)") - parser.add_option("-c", "--calibration", type="eng_float", default=0.0, + + parser.add_option('-f', '--freq', type="eng_float", default=None, + help="Set receive frequency to FREQ [default=%default]", + metavar="FREQ") + parser.add_option("-a", "--address", type="string", default="addr=192.168.10.2", + help="Address of UHD device, [default=%default]") + parser.add_option("-A", "--antenna", type="string", default=None, + help="select Rx Antenna where appropriate") + parser.add_option("", "--rx-gain", type="eng_float", default=None, + help="set receive gain in dB (default is midpoint)") + parser.add_option("-c", "--calibration", type="eng_float", default=0.0, help="set frequency offset to Hz", metavar="Hz") - parser.add_option("-g", "--gain", type="int", - help="set RF gain", metavar="dB") - parser.add_option("-F", "--from-file", default=None, - help="Read from file instead of USRP") + parser.add_option("-v", "--verbose", action="store_true", default=False) parser.add_option("-l", "--log", action="store_true", default=False, help="log flowgraph to files (LOTS of data)") - parser.add_option("-v", "--verbose", action="store_true", default=False, - help="display debug output") + parser.add_option("-F", "--from-file", default=None, + help="read samples from file instead of USRP") + (options, args) = parser.parse_args() - if options.verbose: - print options + if len(args) > 0: + print "Run 'usrp_flex_band.py -h' for options." + sys.exit(1) + + if (options.freq is None): + sys.stderr.write("You must specify -f FREQ or --freq FREQ\n") + sys.exit(1) + + return (options, args) + + +if __name__ == "__main__": + + (options, args) = get_options() queue = gr.msg_queue() tb = app_top_block(options, queue) @@ -105,6 +141,4 @@ def main(): runner.end() - -if __name__ == "__main__": - main() + diff --git a/gr-radio-astronomy/.gitignore b/gr-radio-astronomy/.gitignore deleted file mode 100644 index 8736aba7f..000000000 --- a/gr-radio-astronomy/.gitignore +++ /dev/null @@ -1,22 +0,0 @@ -/Makefile -/Makefile.in -/aclocal.m4 -/configure -/config.h.in -/stamp-h.in -/libtool -/config.log -/config.h -/config.cache -/config.status -/missing -/stamp-h -/stamp-h1 -/.deps -/.libs -/*.la -/*.lo -/autom4te.cache -/*.cache -/missing -/make.log diff --git a/gr-radio-astronomy/Makefile.am b/gr-radio-astronomy/Makefile.am deleted file mode 100644 index b3cecff96..000000000 --- a/gr-radio-astronomy/Makefile.am +++ /dev/null @@ -1,24 +0,0 @@ -# -# Copyright 2004 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. -# - -include $(top_srcdir)/Makefile.common - -SUBDIRS = src diff --git a/gr-radio-astronomy/src/.gitignore b/gr-radio-astronomy/src/.gitignore deleted file mode 100644 index bb3f27777..000000000 --- a/gr-radio-astronomy/src/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -/Makefile -/Makefile.in -/.la -/.lo -/.deps -/.libs -/*.la -/*.lo -/howto.cc -/howto.py diff --git a/gr-radio-astronomy/src/Makefile.am b/gr-radio-astronomy/src/Makefile.am deleted file mode 100644 index be38b7c1a..000000000 --- a/gr-radio-astronomy/src/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright 2004 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. -# - -SUBDIRS = lib -if PYTHON -SUBDIRS += python -endif diff --git a/gr-radio-astronomy/src/lib/.gitignore b/gr-radio-astronomy/src/lib/.gitignore deleted file mode 100644 index 711bfef2c..000000000 --- a/gr-radio-astronomy/src/lib/.gitignore +++ /dev/null @@ -1,16 +0,0 @@ -/Makefile -/Makefile.in -/.la -/.lo -/.deps -/.libs -/*.la -/*.lo -/howto.cc -/howto.py -/ra.cc -/ra.py -/*.pyc -/gnuradio -/guile -/python diff --git a/gr-radio-astronomy/src/lib/Makefile.am b/gr-radio-astronomy/src/lib/Makefile.am deleted file mode 100644 index 1b6b854ea..000000000 --- a/gr-radio-astronomy/src/lib/Makefile.am +++ /dev/null @@ -1,35 +0,0 @@ -# -# Copyright 2004,2005,2006,2008,2009,2010 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. -# - -include $(top_srcdir)/Makefile.common -include $(top_srcdir)/Makefile.swig - -AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(WITH_INCLUDES) - -TOP_SWIG_IFILES = \ - ra.i - -# Install so that they end up available as: -# import gnuradio.ra -# This ends up at: -# ${prefix}/lib/python${python_version}/site-packages/gnuradio -ra_pythondir_category = \ - gnuradio diff --git a/gr-radio-astronomy/src/lib/Makefile.swig.gen b/gr-radio-astronomy/src/lib/Makefile.swig.gen deleted file mode 100644 index faad880cf..000000000 --- a/gr-radio-astronomy/src/lib/Makefile.swig.gen +++ /dev/null @@ -1,145 +0,0 @@ -# -*- Makefile -*- -# -# Copyright 2009 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. -# - -# Makefile.swig.gen for ra.i - -## Default install locations for these files: -## -## Default location for the Python directory is: -## ${prefix}/lib/python${python_version}/site-packages/[category]/ra -## Default location for the Python exec directory is: -## ${exec_prefix}/lib/python${python_version}/site-packages/[category]/ra -## -## The following can be overloaded to change the install location, but -## this has to be done in the including Makefile.am -before- -## Makefile.swig is included. - -ra_pythondir_category ?= gnuradio/ra -ra_pylibdir_category ?= $(ra_pythondir_category) -ra_pythondir = $(pythondir)/$(ra_pythondir_category) -ra_pylibdir = $(pyexecdir)/$(ra_pylibdir_category) - -# The .so libraries for the guile modules get installed whereever guile -# is installed, usually /usr/lib/guile/gnuradio/ -# FIXME: determince whether these should be installed with gnuradio. -ra_scmlibdir = $(libdir) - -# The scm files for the guile modules get installed where ever guile -# is installed, usually /usr/share/guile/site/ra -# FIXME: determince whether these should be installed with gnuradio. -ra_scmdir = $(guiledir) - -## SWIG headers are always installed into the same directory. - -ra_swigincludedir = $(swigincludedir) - -## This is a template file for a "generated" Makefile addition (in -## this case, "Makefile.swig.gen"). By including the top-level -## Makefile.swig, this file will be used to generate the SWIG -## dependencies. Assign the variable TOP_SWIG_FILES to be the list of -## SWIG .i files to generated wrappings for; there can be more than 1 -## so long as the names are unique (no sorting is done on the -## TOP_SWIG_FILES list). This file explicitly assumes that a SWIG .i -## file will generate .cc, .py, and possibly .h files -- meaning that -## all of these files will have the same base name (that provided for -## the SWIG .i file). -## -## This code is setup to ensure parallel MAKE ("-j" or "-jN") does the -## right thing. For more info, see < -## http://sources.redhat.com/automake/automake.html#Multiple-Outputs > - -## Other cleaned files: dependency files generated by SWIG or this Makefile - -MOSTLYCLEANFILES += $(DEPDIR)/*.S* - -## Various SWIG variables. These can be overloaded in the including -## Makefile.am by setting the variable value there, then including -## Makefile.swig . - -ra_swiginclude_HEADERS = \ - ra.i \ - $(ra_swiginclude_headers) - -if PYTHON -ra_pylib_LTLIBRARIES = \ - _ra.la - -_ra_la_SOURCES = \ - python/ra.cc \ - $(ra_la_swig_sources) - -ra_python_PYTHON = \ - ra.py \ - $(ra_python) - -_ra_la_LIBADD = \ - $(STD_SWIG_LA_LIB_ADD) \ - $(ra_la_swig_libadd) - -_ra_la_LDFLAGS = \ - $(STD_SWIG_LA_LD_FLAGS) \ - $(ra_la_swig_ldflags) - -_ra_la_CXXFLAGS = \ - $(STD_SWIG_CXX_FLAGS) \ - -I$(top_builddir) \ - $(ra_la_swig_cxxflags) - -python/ra.cc: ra.py -ra.py: ra.i - -# Include the python dependencies for this file --include python/ra.d - -endif # end of if python - -if GUILE - -ra_scmlib_LTLIBRARIES = \ - libguile-gnuradio-ra.la -libguile_gnuradio_ra_la_SOURCES = \ - guile/ra.cc \ - $(ra_la_swig_sources) -nobase_ra_scm_DATA = \ - gnuradio/ra.scm \ - gnuradio/ra-primitive.scm -libguile_gnuradio_ra_la_LIBADD = \ - $(STD_SWIG_LA_LIB_ADD) \ - $(ra_la_swig_libadd) -libguile_gnuradio_ra_la_LDFLAGS = \ - $(STD_SWIG_LA_LD_FLAGS) \ - $(ra_la_swig_ldflags) -libguile_gnuradio_ra_la_CXXFLAGS = \ - $(STD_SWIG_CXX_FLAGS) \ - -I$(top_builddir) \ - $(ra_la_swig_cxxflags) - -guile/ra.cc: gnuradio/ra.scm -gnuradio/ra.scm: ra.i -gnuradio/ra-primitive.scm: gnuradio/ra.scm - -# Include the guile dependencies for this file --include guile/ra.d - -endif # end of GUILE - - diff --git a/gr-radio-astronomy/src/lib/ra.i b/gr-radio-astronomy/src/lib/ra.i deleted file mode 100644 index 3e8f409e3..000000000 --- a/gr-radio-astronomy/src/lib/ra.i +++ /dev/null @@ -1,67 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2009 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. - */ - -%include "gnuradio.i" // the common stuff - -// We'll need something like this if we add C++ blocks... -// See the gr-howto-write-a-block tarball for examples - -// ---------------------------------------------------------------- - -/* - * First arg is the package prefix. - * Second arg is the name of the class minus the prefix. - * - * This does some behind-the-scenes magic so we can - * access ra_square_ff from python as ra.square_ff - */ -// GR_SWIG_BLOCK_MAGIC(ra,square_ff); - -// ra_square_ff_sptr ra_make_square_ff (); -// -// class ra_square_ff : public gr_block -// { -// private: -// ra_square_ff (); -// }; -// -// // ---------------------------------------------------------------- -// -// GR_SWIG_BLOCK_MAGIC(ra,square2_ff); -// -// ra_square2_ff_sptr ra_make_square2_ff (); -// -// class ra_square2_ff : public gr_sync_block -// { -// private: -// ra_square2_ff (); -// }; - -#if SWIGGUILE -%scheme %{ -(load-extension-global "libguile-gnuradio-ra" "scm_init_gnuradio_ra_module") -%} - -%goops %{ -(use-modules (gnuradio gnuradio_core_runtime)) -%} -#endif diff --git a/gr-radio-astronomy/src/python/.gitignore b/gr-radio-astronomy/src/python/.gitignore deleted file mode 100644 index bf03975bb..000000000 --- a/gr-radio-astronomy/src/python/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -/Makefile -/Makefile.in -/.deps -/.libs -/*.la -/*.lo -/*.pyc -/*.pyo -/run_tests diff --git a/gr-radio-astronomy/src/python/Makefile.am b/gr-radio-astronomy/src/python/Makefile.am deleted file mode 100644 index 2518e0647..000000000 --- a/gr-radio-astronomy/src/python/Makefile.am +++ /dev/null @@ -1,56 +0,0 @@ -# -# Copyright 2004,2006,2009 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. -# - -include $(top_srcdir)/Makefile.common - -# Install this stuff so that it ends up as the gnuradio.ra module -# This usually ends up at: -# ${prefix}/lib/python${python_version}/site-packages/gnuradio - -ourpythondir = $(grpythondir) -ourlibdir = $(grpyexecdir) - -# wxgui stuff here -wxguipythondir = $(grpythondir)/wxgui -wxguilibdir = $(grpyexecdir)/wxgui - -EXTRA_DIST += \ - run_tests.in - -TESTS = run_tests - - -noinst_PYTHON = \ - qa_ra.py - -ourpython_PYTHON = \ - local_calibrator.py - -wxguipython_PYTHON = \ - ra_stripchartsink.py \ - ra_fftsink.py \ - ra_waterfallsink.py - - -# and here for applications you want installed in prefix/bin -dist_bin_SCRIPTS = \ - usrp_ra_receiver.py \ - usrp_psr_receiver.py diff --git a/gr-radio-astronomy/src/python/local_calibrator.py b/gr-radio-astronomy/src/python/local_calibrator.py deleted file mode 100755 index d76060c0f..000000000 --- a/gr-radio-astronomy/src/python/local_calibrator.py +++ /dev/null @@ -1,195 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2003,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. -# - -import Numeric -import math -import ephem -import time - -# -#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -# NO LONGER USED -#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -# -# - - -# -# Simple class for allowing local definition of a calibration function -# for raw samples coming from the RA detector chain. Each observatory -# is different, and rather than hacking up the main code in usrp_ra_receiver -# we define the appropriate function here. -# -# For example, one could calibrate the output in Janskys, rather than -# dB. -# -# - -def calib_default_total_power(data): - r = 10.0*math.log10(data) - return(r) - -def calib_numogate_ridge_observatory_total_power(data): - - me = ephem.Observer() - - # - # PyEphem wants lat/long as strings, rather than floats--took me quite - # a long time to figure that out. If they don't arrive as strings, - # the calculations for sidereal time are complete garbage - # - me.long = globals()["calib_long"] - me.lat = globals()["calib_lat"] - - me.date = ephem.now() - sidtime = me.sidereal_time() - - foo = time.localtime() - if not "calib_prefix" in globals(): - pfx = "./" - else: - pfx = globals()["calib_prefix"] - filenamestr = "%s/%04d%02d%02d%02d" % (pfx, foo.tm_year, - foo.tm_mon, foo.tm_mday, foo.tm_hour) - - numogate_file = open (filenamestr+".tpdat","a") - - r = (data / 409.6) - flt = "%6.3f" % r - #r = calib_default_total_power(data) - inter = globals()["calib_decln"] - integ = globals()["calib_integ_setting"] - fc = globals()["calib_freq_setting"] - fc = fc / 1000000 - bw = globals()["calib_bw_setting"] - bw = bw / 1000000 - ga = globals()["calib_gain_setting"] - - now = time.time() - - if not "calib_then_tpdat" in globals(): - globals()["calib_then_tpdat"] = now - - if (now - globals()["calib_then_tpdat"]) >= 20: - globals()["calib_then_tpdat"] = now - - numogate_file.write(str(ephem.hours(sidtime))+" "+flt+" Dn="+str(inter)+",") - numogate_file.write("Ti="+str(integ)+",Fc="+str(fc)+",Bw="+str(bw)) - numogate_file.write(",Ga="+str(ga)+"\n") - else: - numogate_file.write(str(ephem.hours(sidtime))+" "+flt+"\n") - - numogate_file.close() - return(r) - -def calib_numogate_ridge_observatory_fft(data,l): - - me = ephem.Observer() - - # - # PyEphem wants lat/long as strings, rather than floats--took me quite - # a long time to figure that out. If they don't arrive as strings, - # the calculations for sidereal time are complete garbage - # - me.long = globals()["calib_long"] - me.lat = globals()["calib_lat"] - - me.date = ephem.now() - sidtime = me.sidereal_time() - - foo = time.localtime() - - if not "calib_prefix" in globals(): - pfx = "./" - else: - pfx = globals()["calib_prefix"] - filenamestr = "%s/%04d%02d%02d%02d" % (pfx, foo.tm_year, - foo.tm_mon, foo.tm_mday, foo.tm_hour) - - now = time.time() - - if not "calib_then" in globals(): - globals()["calib_then"] = now - - delta = (l/1024)*5 - - if (now - globals()["calib_then"]) >= delta: - - globals()["calib_then"] = now - numogate_file = open (filenamestr+".sdat","a") - - r = data - inter = globals()["calib_decln"] - fc = globals()["calib_freq_setting"] - fc = fc / 1000000 - bw = globals()["calib_bw_setting"] - bw = bw / 1000000 - av = globals()["calib_avg_alpha"] - numogate_file.write("data:"+str(ephem.hours(sidtime))+" Dn="+str(inter)+",Fc="+str(fc)+",Bw="+str(bw)+",Av="+str(av)) - numogate_file.write(" "+str(r)+"\n") - numogate_file.close() - return(r) - - return(data) - -def calib_default_fft(db,l): - return(db) - -# -# We capture various parameters from the receive chain here, because -# they can affect the calibration equations. -# -# -def calib_set_gain(gain): - globals()["calib_gain_setting"] = gain - globals()["calib_then_tpdat"] = time.time() - 50 - -def calib_set_integ(integ): - globals()["calib_integ_setting"] = integ - globals()["calib_then_tpdat"] = time.time() - 50 - -def calib_set_bw(bw): - globals()["calib_bw_setting"] = bw - globals()["calib_then_tpdat"] = time.time() - 50 - -def calib_set_freq(freq): - globals()["calib_freq_setting"] = freq - globals()["calib_then_tpdat"] = time.time() - 50 - -def calib_set_avg_alpha(alpha): - globals()["calib_avg_alpha"] = alpha - -def calib_set_interesting(inter): - globals()["calib_is_interesting"] = inter - -def calib_set_decln(dec): - globals()["calib_decln"] = dec - globals()["calib_then_tpdat"] = time.time() - 50 - -def calib_set_prefix(pfx): - globals()["calib_prefix"] = pfx - -def calib_set_long(long): - globals()["calib_long"] = long - -def calib_set_lat(lat): - globals()["calib_lat"] = lat diff --git a/gr-radio-astronomy/src/python/qa_ra.py b/gr-radio-astronomy/src/python/qa_ra.py deleted file mode 100755 index 2cb0f42be..000000000 --- a/gr-radio-astronomy/src/python/qa_ra.py +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2004,2006,2010 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. -# - -from gnuradio import gr, gr_unittest -import ra - -class test_radio_astronomy (gr_unittest.TestCase): - - def setUp (self): - self.tb = gr.top_block () - - def tearDown (self): - self.tb = None - - def test_000_(self): # ensure that we can load the module - pass - -if __name__ == '__main__': - gr_unittest.run(test_radio_astronomy, "test_radio_astronomy.xml") diff --git a/gr-radio-astronomy/src/python/ra_fftsink.py b/gr-radio-astronomy/src/python/ra_fftsink.py deleted file mode 100755 index 4733027c1..000000000 --- a/gr-radio-astronomy/src/python/ra_fftsink.py +++ /dev/null @@ -1,501 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2003,2004,2005,2007 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. -# - -from gnuradio import gr, gru, window -from gnuradio.wxgui import stdgui2 -import wx -import gnuradio.wxgui.plot as plot -import numpy -import threading -import math -import random - -default_ra_fftsink_size = (640,140) - - - -class ra_fft_sink_base(object): - def __init__(self, input_is_real=False, baseband_freq=0, y_per_div=10, sc_y_per_div=0.5, ref_level=50, sc_ref_level=20, - sample_rate=1, fft_size=512, fft_rate=15, - average=False, avg_alpha=None, title='', peak_hold=False, ofunc=None, xydfunc=None): - - # initialize common attributes - self.baseband_freq = baseband_freq - self.y_divs = 8 - self.y_per_div=y_per_div - self.sc_y_per_div=sc_y_per_div - self.ref_level = ref_level - self.autoscale = False - self.sc_ref_level = sc_ref_level - self.sample_rate = sample_rate - self.fft_size = fft_size - self.fft_rate = fft_rate - self.binwidth = float(sample_rate/fft_size) - self.average = average - self.ofunc = ofunc - self.xydfunc = xydfunc - self.ofunc = ofunc - if avg_alpha is None: - self.avg_alpha = 2.0 / fft_rate - else: - self.avg_alpha = avg_alpha - self.title = title - self.peak_hold = peak_hold - self.input_is_real = input_is_real - self.msgq = gr.msg_queue(2) # queue that holds a maximum of 2 messages - - def set_y_per_div(self, y_per_div): - self.y_per_div = y_per_div - - - def set_ref_level(self, ref_level): - self.ref_level = ref_level - - def set_average(self, average): - self.average = average - if average: - self.avg.set_taps(self.avg_alpha) - self.set_peak_hold(False) - else: - self.avg.set_taps(1.0) - - def set_peak_hold(self, enable): - self.peak_hold = enable - if enable: - self.set_average(False) - self.win.set_peak_hold(enable) - - def set_autoscale(self, auto): - self.autoscale = auto - - def set_avg_alpha(self, avg_alpha): - self.avg_alpha = avg_alpha - - def set_baseband_freq(self, baseband_freq): - self.baseband_freq = baseband_freq - - -class ra_fft_sink_f(gr.hier_block2, ra_fft_sink_base): - def __init__(self, parent, baseband_freq=0, - y_per_div=10, sc_y_per_div=0.5, sc_ref_level=40, ref_level=50, sample_rate=1, fft_size=512, - fft_rate=15, average=False, avg_alpha=None, title='', - size=default_ra_fftsink_size, peak_hold=False, ofunc=None, - xydfunc=None): - gr.hier_block2.__init__(self, "ra_fft_sink_f", - gr.io_signature(1, 1, gr.sizeof_float), - gr.io_signature(0, 0, 0)) - - ra_fft_sink_base.__init__(self, input_is_real=True, baseband_freq=baseband_freq, - y_per_div=y_per_div, sc_y_per_div=sc_y_per_div, - sc_ref_level=sc_ref_level, ref_level=ref_level, - sample_rate=sample_rate, fft_size=fft_size, - fft_rate=fft_rate, - average=average, avg_alpha=avg_alpha, title=title, - peak_hold=peak_hold, ofunc=ofunc, - xydfunc=xydfunc) - - self.binwidth = float(sample_rate/2.0)/float(fft_size) - s2p = gr.serial_to_parallel(gr.sizeof_float, fft_size) - one_in_n = gr.keep_one_in_n(gr.sizeof_float * fft_size, - max(1, int(sample_rate/fft_size/fft_rate))) - mywindow = window.blackmanharris(fft_size) - fft = gr.fft_vfc(fft_size, True, mywindow) - c2mag = gr.complex_to_mag(fft_size) - self.avg = gr.single_pole_iir_filter_ff(1.0, fft_size) - log = gr.nlog10_ff(20, fft_size, -20*math.log10(fft_size)) - sink = gr.message_sink(gr.sizeof_float * fft_size, self.msgq, True) - - self.connect (self, s2p, one_in_n, fft, c2mag, self.avg, log, sink) - - self.win = fft_window(self, parent, size=size) - self.set_average(self.average) - -class ra_fft_sink_c(gr.hier_block2, ra_fft_sink_base): - def __init__(self, parent, baseband_freq=0, - y_per_div=10, sc_y_per_div=0.5, sc_ref_level=40, - ref_level=50, sample_rate=1, fft_size=512, - fft_rate=15, average=False, avg_alpha=None, title='', - size=default_ra_fftsink_size, peak_hold=False, ofunc=None, xydfunc=None): - - gr.hier_block2.__init__(self, "ra_fft_sink_c", - gr.io_signature(1, 1, gr.sizeof_gr_complex), - gr.io_signature(0, 0, 0)) - - - ra_fft_sink_base.__init__(self, input_is_real=False, baseband_freq=baseband_freq, - y_per_div=y_per_div, sc_y_per_div=sc_y_per_div, - sc_ref_level=sc_ref_level, ref_level=ref_level, - sample_rate=sample_rate, fft_size=fft_size, - fft_rate=fft_rate, - average=average, avg_alpha=avg_alpha, - title=title, - peak_hold=peak_hold, ofunc=ofunc, - xydfunc=xydfunc) - - s2p = gr.serial_to_parallel(gr.sizeof_gr_complex, fft_size) - one_in_n = gr.keep_one_in_n(gr.sizeof_gr_complex * fft_size, - max(1, int(sample_rate/fft_size/fft_rate))) - mywindow = window.blackmanharris(fft_size) - fft = gr.fft_vcc(fft_size, True, mywindow) - c2mag = gr.complex_to_mag(fft_size) - self.avg = gr.single_pole_iir_filter_ff(1.0, fft_size) - log = gr.nlog10_ff(20, fft_size, -20*math.log10(fft_size)) - sink = gr.message_sink(gr.sizeof_float * fft_size, self.msgq, True) - - self.connect(self, s2p, one_in_n, fft, c2mag, self.avg, log, sink) - - self.win = fft_window(self, parent, size=size) - self.set_average(self.average) - - -# ------------------------------------------------------------------------ - -myDATA_EVENT = wx.NewEventType() -EVT_DATA_EVENT = wx.PyEventBinder (myDATA_EVENT, 0) - - -class DataEvent(wx.PyEvent): - def __init__(self, data): - wx.PyEvent.__init__(self) - self.SetEventType (myDATA_EVENT) - self.data = data - - def Clone (self): - self.__class__ (self.GetId()) - - -class input_watcher (threading.Thread): - def __init__ (self, msgq, fft_size, event_receiver, **kwds): - threading.Thread.__init__ (self, **kwds) - self.setDaemon (1) - self.msgq = msgq - self.fft_size = fft_size - self.event_receiver = event_receiver - self.keep_running = True - self.start () - - def run (self): - while (self.keep_running): - msg = self.msgq.delete_head() # blocking read of message queue - itemsize = int(msg.arg1()) - nitems = int(msg.arg2()) - - s = msg.to_string() # get the body of the msg as a string - - # There may be more than one FFT frame in the message. - # If so, we take only the last one - if nitems > 1: - start = itemsize * (nitems - 1) - s = s[start:start+itemsize] - - complex_data = numpy.fromstring (s, numpy.float32) - de = DataEvent (complex_data) - wx.PostEvent (self.event_receiver, de) - del de - - -class fft_window (plot.PlotCanvas): - def __init__ (self, ra_fftsink, parent, id = -1, - pos = wx.DefaultPosition, size = wx.DefaultSize, - style = wx.DEFAULT_FRAME_STYLE, name = ""): - plot.PlotCanvas.__init__ (self, parent, id, pos, size, style, name) - - self.y_range = None - self.ra_fftsink = ra_fftsink - self.peak_hold = False - self.peak_vals = None - - self.SetEnableGrid (True) - # self.SetEnableZoom (True) - # self.SetBackgroundColour ('black') - - self.build_popup_menu() - - EVT_DATA_EVENT (self, self.set_data) - wx.EVT_CLOSE (self, self.on_close_window) - self.Bind(wx.EVT_RIGHT_UP, self.on_right_click) - self.Bind(wx.EVT_LEFT_UP, self.on_left_click) - self.Bind(wx.EVT_MOTION, self.on_motion) - - self.input_watcher = input_watcher(ra_fftsink.msgq, ra_fftsink.fft_size, self) - - - def on_close_window (self, event): - print "fft_window:on_close_window" - self.keep_running = False - - - def set_data (self, evt): - calc_min = 99e10 - calc_max = -99e10 - dB = evt.data - L = len (dB) - - calc_min = min(dB) - calc_max = max(dB) - - if (self.ra_fftsink.ofunc != None): - self.ra_fftsink.ofunc(evt.data,L) - - if self.peak_hold: - if self.peak_vals is None: - self.peak_vals = dB - else: - self.peak_vals = numpy.maximum(dB, self.peak_vals) - dB = self.peak_vals - - x = max(abs(self.ra_fftsink.sample_rate), abs(self.ra_fftsink.baseband_freq)) - if x >= 1e9: - sf = 1e-9 - units = "GHz" - elif x >= 1e6: - sf = 1e-6 - units = "MHz" - elif x >= 1e3: - sf = 1e-3 - units = "kHz" - else: - sf = 1.0 - units = "Hz" - - if self.ra_fftsink.input_is_real: # only plot 1/2 the points - x_vals = ((numpy.arange (L/2) - * (self.ra_fftsink.sample_rate * sf / L)) - + self.ra_fftsink.baseband_freq * sf) - points = numpy.zeros((len(x_vals), 2), numpy.float64) - points[:,0] = x_vals - points[:,1] = dB[0:L/2] - else: - # the "negative freqs" are in the second half of the array - x_vals = ((numpy.arange(-L/2, L/2) - * (self.ra_fftsink.sample_rate * sf / L)) - + self.ra_fftsink.baseband_freq * sf) - points = numpy.zeros((len(x_vals), 2), numpy.float64) - points[:,0] = x_vals - points[:,1] = numpy.concatenate ((dB[L/2:], dB[0:L/2])) - - lines = plot.PolyLine (points, colour='BLUE') - graphics = plot.PlotGraphics ([lines], - title=self.ra_fftsink.title, - xLabel = units, yLabel = "dB") - - self.Draw (graphics, xAxis=None, yAxis=self.y_range) - d = calc_max - calc_min - d = d * 0.1 - if self.ra_fftsink.autoscale == True: - self.y_range = self._axisInterval ('min', calc_min-d, calc_max+d) - else: - self.update_y_range () - - def set_peak_hold(self, enable): - self.peak_hold = enable - self.peak_vals = None - - def update_y_range (self): - ymax = self.ra_fftsink.ref_level - ymin = self.ra_fftsink.ref_level - self.ra_fftsink.y_per_div * self.ra_fftsink.y_divs - self.y_range = self._axisInterval ('min', ymin, ymax) - - def on_average(self, evt): - # print "on_average" - self.ra_fftsink.set_average(evt.IsChecked()) - - def on_peak_hold(self, evt): - # print "on_peak_hold" - self.ra_fftsink.set_peak_hold(evt.IsChecked()) - - def on_autoscale(self, evt): - self.ra_fftsink.set_autoscale(evt.IsChecked()) - - def on_incr_ref_level(self, evt): - # print "on_incr_ref_level" - self.ra_fftsink.set_ref_level(self.ra_fftsink.ref_level - + self.ra_fftsink.y_per_div) - - def on_decr_ref_level(self, evt): - # print "on_decr_ref_level" - self.ra_fftsink.set_ref_level(self.ra_fftsink.ref_level - - self.ra_fftsink.y_per_div) - - def on_incr_y_per_div(self, evt): - # print "on_incr_y_per_div" - self.ra_fftsink.set_y_per_div(next_up(self.ra_fftsink.y_per_div, (0.5,1,2,5,10))) - - def on_decr_y_per_div(self, evt): - # print "on_decr_y_per_div" - self.ra_fftsink.set_y_per_div(next_down(self.ra_fftsink.y_per_div, (0.5,1,2,5,10))) - - def on_y_per_div(self, evt): - # print "on_y_per_div" - Id = evt.GetId() - if Id == self.id_y_per_div_1: - self.ra_fftsink.set_y_per_div(0.5) - elif Id == self.id_y_per_div_2: - self.ra_fftsink.set_y_per_div(1.0) - elif Id == self.id_y_per_div_5: - self.ra_fftsink.set_y_per_div(2.0) - elif Id == self.id_y_per_div_10: - self.ra_fftsink.set_y_per_div(5.0) - elif Id == self.id_y_per_div_20: - self.ra_fftsink.set_y_per_div(10) - - - def on_right_click(self, event): - menu = self.popup_menu - for id, pred in self.checkmarks.items(): - item = menu.FindItemById(id) - item.Check(pred()) - self.PopupMenu(menu, event.GetPosition()) - - def on_motion(self, event): - if not self.ra_fftsink.xydfunc == None: - xy = self.GetXY(event) - self.ra_fftsink.xydfunc (0,xy) - - def on_left_click(self,event): - if not self.ra_fftsink.xydfunc == None: - xy = self.GetXY(event) - self.ra_fftsink.xydfunc (1,xy) - - def build_popup_menu(self): - self.id_incr_ref_level = wx.NewId() - self.id_decr_ref_level = wx.NewId() - self.id_autoscale = wx.NewId() - self.id_incr_y_per_div = wx.NewId() - self.id_decr_y_per_div = wx.NewId() - self.id_y_per_div_1 = wx.NewId() - self.id_y_per_div_2 = wx.NewId() - self.id_y_per_div_5 = wx.NewId() - self.id_y_per_div_10 = wx.NewId() - self.id_y_per_div_20 = wx.NewId() - self.id_average = wx.NewId() - self.id_peak_hold = wx.NewId() - - self.Bind(wx.EVT_MENU, self.on_average, id=self.id_average) - self.Bind(wx.EVT_MENU, self.on_peak_hold, id=self.id_peak_hold) - self.Bind(wx.EVT_MENU, self.on_autoscale, id=self.id_autoscale) - self.Bind(wx.EVT_MENU, self.on_incr_ref_level, id=self.id_incr_ref_level) - self.Bind(wx.EVT_MENU, self.on_decr_ref_level, id=self.id_decr_ref_level) - self.Bind(wx.EVT_MENU, self.on_incr_y_per_div, id=self.id_incr_y_per_div) - self.Bind(wx.EVT_MENU, self.on_decr_y_per_div, id=self.id_decr_y_per_div) - self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_1) - self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_2) - self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_5) - self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_10) - self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_20) - - - # make a menu - menu = wx.Menu() - self.popup_menu = menu - menu.AppendCheckItem(self.id_average, "Average") - menu.AppendCheckItem(self.id_peak_hold, "Peak Hold") - menu.Append(self.id_incr_ref_level, "Incr Ref Level") - menu.Append(self.id_decr_ref_level, "Decr Ref Level") - # menu.Append(self.id_incr_y_per_div, "Incr dB/div") - # menu.Append(self.id_decr_y_per_div, "Decr dB/div") - menu.AppendSeparator() - # we'd use RadioItems for these, but they're not supported on Mac - menu.AppendCheckItem(self.id_autoscale, "Autoscale") - menu.AppendCheckItem(self.id_y_per_div_1, "0.5 dB/div") - menu.AppendCheckItem(self.id_y_per_div_2, "1.0 dB/div") - menu.AppendCheckItem(self.id_y_per_div_5, "2.0 dB/div") - menu.AppendCheckItem(self.id_y_per_div_10, "5.0 dB/div") - menu.AppendCheckItem(self.id_y_per_div_20, "10.0 dB/div") - - self.checkmarks = { - self.id_average : lambda : self.ra_fftsink.average, - self.id_peak_hold : lambda : self.ra_fftsink.peak_hold, - self.id_autoscale : lambda : self.ra_fftsink.autoscale, - self.id_y_per_div_1 : lambda : self.ra_fftsink.y_per_div == 0.5, - self.id_y_per_div_2 : lambda : self.ra_fftsink.y_per_div == 1.0, - self.id_y_per_div_5 : lambda : self.ra_fftsink.y_per_div == 2.0, - self.id_y_per_div_10 : lambda : self.ra_fftsink.y_per_div == 5.0, - self.id_y_per_div_20 : lambda : self.ra_fftsink.y_per_div == 10.0, - } - - -def next_up(v, seq): - """ - Return the first item in seq that is > v. - """ - for s in seq: - if s > v: - return s - return v - -def next_down(v, seq): - """ - Return the last item in seq that is < v. - """ - rseq = list(seq[:]) - rseq.reverse() - - for s in rseq: - if s < v: - return s - return v - - -# ---------------------------------------------------------------- -# Standalone test app -# ---------------------------------------------------------------- - -class test_app_flow_graph (stdgui2.std_top_block): - def __init__(self, frame, panel, vbox, argv): - stdgui2.std_top_block.__init__ (self, frame, panel, vbox, argv) - - fft_size = 256 - - # build our flow graph - input_rate = 20.000e3 - - # Generate a complex sinusoid - src1 = gr.sig_source_c (input_rate, gr.GR_SIN_WAVE, 5.75e3, 1000) - #src1 = gr.sig_source_c (input_rate, gr.GR_CONST_WAVE, 5.75e3, 1000) - - # We add these throttle blocks so that this demo doesn't - # suck down all the CPU available. Normally you wouldn't use these. - thr1 = gr.throttle(gr.sizeof_gr_complex, input_rate) - - sink1 = ra_fft_sink_c (panel, title="Complex Data", fft_size=fft_size, - sample_rate=input_rate, baseband_freq=100e3, - ref_level=60, y_per_div=10) - vbox.Add (sink1.win, 1, wx.EXPAND) - self.connect (src1, thr1, sink1) - - src2 = gr.sig_source_f (input_rate, gr.GR_SIN_WAVE, 5.75e3, 1000) - #src2 = gr.sig_source_f (input_rate, gr.GR_CONST_WAVE, 5.75e3, 1000) - thr2 = gr.throttle(gr.sizeof_float, input_rate) - sink2 = ra_fft_sink_f (panel, title="Real Data", fft_size=fft_size*2, - sample_rate=input_rate, baseband_freq=100e3, - ref_level=60, y_per_div=10) - vbox.Add (sink2.win, 1, wx.EXPAND) - self.connect (src2, thr2, sink2) - -def main (): - app = stdgui2.stdapp (test_app_flow_graph, - "FFT Sink Test App") - app.MainLoop () - -if __name__ == '__main__': - main () diff --git a/gr-radio-astronomy/src/python/ra_stripchartsink.py b/gr-radio-astronomy/src/python/ra_stripchartsink.py deleted file mode 100755 index 76988f8f0..000000000 --- a/gr-radio-astronomy/src/python/ra_stripchartsink.py +++ /dev/null @@ -1,400 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2003,2004,2005,2007 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. -# - -from gnuradio import gr, gru -from gnuradio.wxgui import stdgui2 -import wx -import gnuradio.wxgui.plot as plot -import Numeric -import threading -import math -import ephem -import time - -default_stripchartsink_size = (640,140) -global_yvalues = [] - -class stripchart_sink_base(object): - def __init__(self, input_is_real=False, y_per_div=10, ref_level=50, - sample_rate=1, stripsize=4, - title='',xlabel="X", ylabel="Y", divbase=0.025, - parallel=False, scaling=1.0, autoscale=False): - - # initialize common attributes - self.y_divs = 8 - self.y_per_div=y_per_div - self.ref_level = ref_level - self.autoscale = autoscale - self.sample_rate = sample_rate - self.parallel = parallel - self.title = title - self.xlabel = xlabel - self.ylabel = ylabel - self.divbase = divbase - self.scaling = scaling - self.input_is_real = input_is_real - self.msgq = gr.msg_queue(2) # queue that holds a maximum of 2 messages - self.vector=Numeric.zeros(stripsize,Numeric.Float64) - self.wcnt = 0 - self.timecnt = 0 - self.stripsize=stripsize - - def set_y_per_div(self, y_per_div): - self.y_per_div = y_per_div - - def set_ref_level(self, ref_level): - self.ref_level = ref_level - - def set_autoscale(self, auto): - self.autoscale = auto - -class stripchart_sink_f(gr.hier_block2, stripchart_sink_base): - def __init__(self, parent, - y_per_div=10, ref_level=50, sample_rate=1, - title='', stripsize=4, - size=default_stripchartsink_size,xlabel="X", - ylabel="Y", divbase=0.025, - parallel=False, scaling=1.0, autoscale=False): - - if parallel == False: - gr.hier_block2.__init__(self, "stripchart_sink_f", - gr.io_signature(1, 1, gr.sizeof_float), - gr.io_signature(0, 0, 0)) - else: - gr.hier_block2.__init__(self, "stripchart_sink_f", - gr.io_signature(1, 1, gr.sizeof_float*stripsize), - gr.io_signature(0, 0, 0)) - - - stripchart_sink_base.__init__(self, input_is_real=True, - y_per_div=y_per_div, ref_level=ref_level, - sample_rate=sample_rate, - stripsize=stripsize, - xlabel=xlabel, ylabel=ylabel, - divbase=divbase, title=title, - parallel=parallel, - scaling=scaling, autoscale=autoscale) - - if (parallel == True): - one = gr.keep_one_in_n (gr.sizeof_float*stripsize, 1) - sink = gr.message_sink(gr.sizeof_float*stripsize, self.msgq, True) - else: - one = gr.keep_one_in_n (gr.sizeof_float, 1) - sink = gr.message_sink(gr.sizeof_float, self.msgq, True) - self.connect (self, one, sink) - - self.win = stripchart_window(self, parent, size=size) - - - -# ------------------------------------------------------------------------ - -myDATA_EVENT = wx.NewEventType() -EVT_DATA_EVENT = wx.PyEventBinder (myDATA_EVENT, 0) - - -class DataEvent(wx.PyEvent): - def __init__(self, data): - wx.PyEvent.__init__(self) - self.SetEventType (myDATA_EVENT) - self.data = data - - def Clone (self): - self.__class__ (self.GetId()) - - -class input_watcher (threading.Thread): - def __init__ (self, msgq, evsize, event_receiver, **kwds): - threading.Thread.__init__ (self, **kwds) - self.setDaemon (1) - self.msgq = msgq - self.evsize = evsize - self.event_receiver = event_receiver - self.keep_running = True - self.start () - - def run (self): - while (self.keep_running): - msg = self.msgq.delete_head() # blocking read of message queue - itemsize = int(msg.arg1()) - nitems = int(msg.arg2()) - - s = msg.to_string() # get the body of the msg as a string - - # There may be more than one frame in the message. - # If so, we take only the last one - if nitems > 1: - start = itemsize * (nitems - 1) - s = s[start:start+itemsize] - - complex_data = Numeric.fromstring (s, Numeric.Float32) - de = DataEvent (complex_data) - wx.PostEvent (self.event_receiver, de) - del de - -class stripchart_window(plot.PlotCanvas): - def __init__ (self, stripchartsink, parent, id = -1, - pos = wx.DefaultPosition, size = wx.DefaultSize, - style = wx.DEFAULT_FRAME_STYLE, name = ""): - plot.PlotCanvas.__init__ (self, parent, id, pos, size, style, name) - - self.y_range = None - self.stripchartsink = stripchartsink - - self.SetEnableGrid (True) - # self.SetEnableZoom (True) - # self.SetBackgroundColour ('black') - - self.build_popup_menu() - - EVT_DATA_EVENT (self, self.set_data) - - wx.EVT_CLOSE (self, self.on_close_window) - self.Bind(wx.EVT_RIGHT_UP, self.on_right_click) - - self.input_watcher = input_watcher(stripchartsink.msgq, 1, self) - - - def on_close_window (self, event): - print "stripchart_window:on_close_window" - self.keep_running = False - - - def set_data (self, evt): - indata = evt.data - L = len (indata) - - calc_min = min(indata) - calc_max = max(indata) - d = calc_max - calc_min - d = d * 0.1 - if self.stripchartsink.autoscale == True and self.stripchartsink.parallel == True: - self.y_range = self._axisInterval ('min', calc_min-d, calc_max+d) - - N = self.stripchartsink.stripsize - if self.stripchartsink.parallel != True: - for i in range(1,N): - pooey = N-i - self.stripchartsink.vector[pooey] = self.stripchartsink.vector[pooey-1] - - self.stripchartsink.vector[0] = indata - - else: - self.stripchartsink.vector = indata - - if self.stripchartsink.parallel == True: - avg = 0 - for i in range(0,self.stripchartsink.stripsize): - if self.stripchartsink.vector[i] > 0: - avg += self.stripchartsink.vector[i] - if self.stripchartsink.vector[i] < calc_min: - calc_min = self.stripchartsink.vector[i] - if self.stripchartsink.vector[i] > calc_max: - calc_max = self.stripchartsink.vector[i] - - avg /= self.stripchartsink.stripsize - markers = [] - placedmarkers = 0 - for i in range(0,self.stripchartsink.stripsize): - if (self.stripchartsink.vector[i] > 0 and - self.stripchartsink.vector[i] > (avg*5)): - markers.append((i*self.stripchartsink.scaling, - self.stripchartsink.vector[i])) - placedmarkers += 1 - - points = Numeric.zeros((N,2), Numeric.Float64) - for i in range(0,N): - if self.stripchartsink.scaling == 1.0: - points[i,0] = i - else: - points[i,0] = i * self.stripchartsink.scaling - points[i,1] = self.stripchartsink.vector[i] - - if self.stripchartsink.parallel == True and placedmarkers > 1: - for i in range(0,N): - self.stripchartsink.vector[i] = 0 - - marks = plot.PolyMarker(markers, colour='BLACK', marker='triangle_down') - - lines = plot.PolyLine (points, colour='RED') - - # Temporary--I'm find the markers distracting - placedmarkers = 0 - xlab = self.stripchartsink.xlabel - ylab = self.stripchartsink.ylabel - if (self.stripchartsink.parallel == False) or (placedmarkers <= 1): - graphics = plot.PlotGraphics ([lines], - title=self.stripchartsink.title, - xLabel = xlab, yLabel = ylab) - - else: - graphics = plot.PlotGraphics ([lines,marks], - title=self.stripchartsink.title, - xLabel = xlab, yLabel = ylab) - - self.Draw (graphics, xAxis=None, yAxis=self.y_range) - - if self.stripchartsink.autoscale == False or self.stripchartsink.parallel == False: - self.update_y_range () - - - def update_y_range (self): - ymax = self.stripchartsink.ref_level - ymin = self.stripchartsink.ref_level - self.stripchartsink.y_per_div * self.stripchartsink.y_divs - self.y_range = self._axisInterval ('min', ymin, ymax) - - def on_incr_ref_level(self, evt): - # print "on_incr_ref_level" - self.stripchartsink.set_ref_level(self.stripchartsink.ref_level - + self.stripchartsink.y_per_div) - - def on_decr_ref_level(self, evt): - # print "on_decr_ref_level" - self.stripchartsink.set_ref_level(self.stripchartsink.ref_level - - self.stripchartsink.y_per_div) - - def on_autoscale(self, evt): - self.stripchartsink.set_autoscale(evt.IsChecked()) - - def on_incr_y_per_div(self, evt): - divbase = self.stripchartsink.divbase - x1 = 1 * divbase - x2 = 2 * divbase - x4 = 4 * divbase - x10 = 10 * divbase - x20 = 20 * divbase - # print "on_incr_y_per_div" - self.stripchartsink.set_y_per_div(next_up(self.stripchartsink.y_per_div, (x1,x2,x4,x10,x20))) - - def on_decr_y_per_div(self, evt): - # print "on_decr_y_per_div" - divbase = self.stripchartsink.divbase - x1 = 1 * divbase - x2 = 2 * divbase - x4 = 4 * divbase - x10 = 10 * divbase - x20 = 20 * divbase - self.stripchartsink.set_y_per_div(next_down(self.stripchartsink.y_per_div, (x1,x2,x4,x10,x20))) - - def on_y_per_div(self, evt): - # print "on_y_per_div" - divbase=self.stripchartsink.divbase - Id = evt.GetId() - if Id == self.id_y_per_div_1: - self.stripchartsink.set_y_per_div(1*divbase) - elif Id == self.id_y_per_div_2: - self.stripchartsink.set_y_per_div(2*divbase) - elif Id == self.id_y_per_div_5: - self.stripchartsink.set_y_per_div(4*divbase) - elif Id == self.id_y_per_div_10: - self.stripchartsink.set_y_per_div(10*divbase) - elif Id == self.id_y_per_div_20: - self.stripchartsink.set_y_per_div(20*divbase) - - - def on_right_click(self, event): - menu = self.popup_menu - for id, pred in self.checkmarks.items(): - item = menu.FindItemById(id) - item.Check(pred()) - self.PopupMenu(menu, event.GetPosition()) - - - def build_popup_menu(self): - divbase=self.stripchartsink.divbase - self.id_incr_ref_level = wx.NewId() - self.id_decr_ref_level = wx.NewId() - self.id_autoscale = wx.NewId() - self.id_incr_y_per_div = wx.NewId() - self.id_decr_y_per_div = wx.NewId() - self.id_y_per_div_1 = wx.NewId() - self.id_y_per_div_2 = wx.NewId() - self.id_y_per_div_5 = wx.NewId() - self.id_y_per_div_10 = wx.NewId() - self.id_y_per_div_20 = wx.NewId() - - self.Bind(wx.EVT_MENU, self.on_incr_ref_level, id=self.id_incr_ref_level) - self.Bind(wx.EVT_MENU, self.on_decr_ref_level, id=self.id_decr_ref_level) - self.Bind(wx.EVT_MENU, self.on_autoscale, id=self.id_autoscale) - self.Bind(wx.EVT_MENU, self.on_incr_y_per_div, id=self.id_incr_y_per_div) - self.Bind(wx.EVT_MENU, self.on_decr_y_per_div, id=self.id_decr_y_per_div) - self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_1) - self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_2) - self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_5) - self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_10) - self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_20) - - - # make a menu - menu = wx.Menu() - self.popup_menu = menu - menu.Append(self.id_incr_ref_level, "Incr Ref Level") - menu.Append(self.id_decr_ref_level, "Decr Ref Level") - menu.AppendSeparator() - menu.AppendCheckItem(self.id_autoscale, "Auto Scale") - # we'd use RadioItems for these, but they're not supported on Mac - v = 1.0*divbase - s = "%.3f" % v - menu.AppendCheckItem(self.id_y_per_div_1, s) - v = 2.0*divbase - s = "%.3f" % v - menu.AppendCheckItem(self.id_y_per_div_2, s) - v = 4.0*divbase - s = "%.3f" % v - menu.AppendCheckItem(self.id_y_per_div_5, s) - v = 10*divbase - s = "%.3f" % v - menu.AppendCheckItem(self.id_y_per_div_10, s) - v = 20*divbase - s = "%.3f" % v - menu.AppendCheckItem(self.id_y_per_div_20, s) - - self.checkmarks = { - self.id_autoscale : lambda : self.stripchartsink.autoscale, - self.id_y_per_div_1 : lambda : self.stripchartsink.y_per_div == 1*divbase, - self.id_y_per_div_2 : lambda : self.stripchartsink.y_per_div == 2*divbase, - self.id_y_per_div_5 : lambda : self.stripchartsink.y_per_div == 4*divbase, - self.id_y_per_div_10 : lambda : self.stripchartsink.y_per_div == 10*divbase, - self.id_y_per_div_20 : lambda : self.stripchartsink.y_per_div == 20*divbase, - } - - -def next_up(v, seq): - """ - Return the first item in seq that is > v. - """ - for s in seq: - if s > v: - return s - return v - -def next_down(v, seq): - """ - Return the last item in seq that is < v. - """ - rseq = list(seq[:]) - rseq.reverse() - - for s in rseq: - if s < v: - return s - return v diff --git a/gr-radio-astronomy/src/python/ra_waterfallsink.py b/gr-radio-astronomy/src/python/ra_waterfallsink.py deleted file mode 100755 index e946f3a10..000000000 --- a/gr-radio-astronomy/src/python/ra_waterfallsink.py +++ /dev/null @@ -1,646 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2003,2004,2005,2007 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 2, 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. -# - -from gnuradio import gr, gru, window -from gnuradio.wxgui import stdgui2 -import wx -import gnuradio.wxgui.plot as plot -import numpy -import os -import threading -import math - -default_fftsink_size = (640,240) -default_fft_rate = gr.prefs().get_long('wxgui', 'fft_rate', 15) - -def axis_design( x1, x2, nx ): - # Given start, end, and number of labels, return value of first label, - # increment between labels, number of unlabeled division between labels, - # and scale factor. - - dx = abs( x2 - x1 )/float(nx+1) # allow for space at each end - ldx = math.log10(dx) - l2 = math.log10(2.) - l5 = math.log10(5.) - le = math.floor(ldx) - lf = ldx - le - if lf < l2/2: - c = 1 - dt = 10 - elif lf < (l2+l5)/2: - c = 2 - dt = 4 - elif lf < (l5+1)/2: - c = 5 - dt = 5 - else: - c = 1 - dt = 10 - le += 1 - inc = c*pow( 10., le ) - first = math.ceil( x1/inc )*inc - scale = 1. - while ( abs(x1*scale) >= 1e5 ) or ( abs(x2*scale) >= 1e5 ): - scale *= 1e-3 - return ( first, inc, dt, scale ) - - -class waterfall_sink_base(object): - def __init__(self, input_is_real=False, baseband_freq=0, - sample_rate=1, fft_size=512, - fft_rate=default_fft_rate, - average=False, avg_alpha=None, title='', ofunc=None, xydfunc=None): - - # initialize common attributes - self.baseband_freq = baseband_freq - self.sample_rate = sample_rate - self.fft_size = fft_size - self.fft_rate = fft_rate - self.average = average - self.ofunc = ofunc - self.xydfunc = xydfunc - if avg_alpha is None: - self.avg_alpha = 2.0 / fft_rate - else: - self.avg_alpha = avg_alpha - self.title = title - self.input_is_real = input_is_real - self.msgq = gr.msg_queue(2) # queue up to 2 messages - - def set_average(self, average): - self.average = average - if average: - self.avg.set_taps(self.avg_alpha) - else: - self.avg.set_taps(1.0) - - def set_avg_alpha(self, avg_alpha): - self.avg_alpha = avg_alpha - - def set_baseband_freq(self, baseband_freq): - self.baseband_freq = baseband_freq - - def set_sample_rate(self, sample_rate): - self.sample_rate = sample_rate - self._set_n() - - def _set_n(self): - self.one_in_n.set_n(max(1, int(self.sample_rate/self.fft_size/self.fft_rate))) - -class waterfall_sink_f(gr.hier_block2, waterfall_sink_base): - def __init__(self, parent, baseband_freq=0, - ref_level=0, sample_rate=1, fft_size=512, - fft_rate=default_fft_rate, average=False, avg_alpha=None, - title='', size=default_fftsink_size, report=None, span=40, ofunc=None, xydfunc=None): - - gr.hier_block2.__init__(self, "waterfall_sink_f", - gr.io_signature(1, 1, gr.sizeof_float), - gr.io_signature(0, 0, 0)) - - waterfall_sink_base.__init__(self, input_is_real=True, - baseband_freq=baseband_freq, - sample_rate=sample_rate, - fft_size=fft_size, fft_rate=fft_rate, - average=average, avg_alpha=avg_alpha, - title=title) - - s2p = gr.serial_to_parallel(gr.sizeof_float, self.fft_size) - self.one_in_n = gr.keep_one_in_n(gr.sizeof_float * self.fft_size, - max(1, int(self.sample_rate/self.fft_size/self.fft_rate))) - mywindow = window.blackmanharris(self.fft_size) - fft = gr.fft_vfc(self.fft_size, True, mywindow) - c2mag = gr.complex_to_mag(self.fft_size) - self.avg = gr.single_pole_iir_filter_ff(1.0, self.fft_size) - log = gr.nlog10_ff(20, self.fft_size, -20*math.log10(self.fft_size)) - sink = gr.message_sink(gr.sizeof_float * self.fft_size, self.msgq, True) - - self.connect(self, s2p, self.one_in_n, fft, c2mag, self.avg, log, sink) - self.win = waterfall_window(self, parent, size=size, report=report, - ref_level=ref_level, span=span, ofunc=ofunc, xydfunc=xydfunc) - self.set_average(self.average) - - -class waterfall_sink_c(gr.hier_block2, waterfall_sink_base): - def __init__(self, parent, baseband_freq=0, - ref_level=0, sample_rate=1, fft_size=512, - fft_rate=default_fft_rate, average=False, avg_alpha=None, - title='', size=default_fftsink_size, report=None, span=40, ofunc=None, xydfunc=None): - - gr.hier_block2.__init__(self, "waterfall_sink_c", - gr.io_signature(1, 1, gr.sizeof_gr_complex), - gr.io_signature(0, 0, 0)) - - waterfall_sink_base.__init__(self, input_is_real=False, - baseband_freq=baseband_freq, - sample_rate=sample_rate, - fft_size=fft_size, - fft_rate=fft_rate, - average=average, avg_alpha=avg_alpha, - title=title) - - s2p = gr.serial_to_parallel(gr.sizeof_gr_complex, self.fft_size) - self.one_in_n = gr.keep_one_in_n(gr.sizeof_gr_complex * self.fft_size, - max(1, int(self.sample_rate/self.fft_size/self.fft_rate))) - - mywindow = window.blackmanharris(self.fft_size) - fft = gr.fft_vcc(self.fft_size, True, mywindow) - c2mag = gr.complex_to_mag(self.fft_size) - self.avg = gr.single_pole_iir_filter_ff(1.0, self.fft_size) - log = gr.nlog10_ff(20, self.fft_size, -20*math.log10(self.fft_size)) - sink = gr.message_sink(gr.sizeof_float * self.fft_size, self.msgq, True) - - self.connect(self, s2p, self.one_in_n, fft, c2mag, self.avg, log, sink) - self.win = waterfall_window(self, parent, size=size, report=report, - ref_level=ref_level, span=span, ofunc=ofunc, xydfunc=xydfunc) - self.set_average(self.average) - - -# ------------------------------------------------------------------------ - -myDATA_EVENT = wx.NewEventType() -EVT_DATA_EVENT = wx.PyEventBinder (myDATA_EVENT, 0) - - -class DataEvent(wx.PyEvent): - def __init__(self, data): - wx.PyEvent.__init__(self) - self.SetEventType (myDATA_EVENT) - self.data = data - - def Clone (self): - self.__class__ (self.GetId()) - - -class input_watcher (threading.Thread): - def __init__ (self, msgq, fft_size, event_receiver, **kwds): - threading.Thread.__init__ (self, **kwds) - self.setDaemon (1) - self.msgq = msgq - self.fft_size = fft_size - self.event_receiver = event_receiver - self.keep_running = True - self.start () - - def run (self): - while (self.keep_running): - msg = self.msgq.delete_head() # blocking read of message queue - itemsize = int(msg.arg1()) - nitems = int(msg.arg2()) - - s = msg.to_string() # get the body of the msg as a string - - # There may be more than one FFT frame in the message. - # If so, we take only the last one - if nitems > 1: - start = itemsize * (nitems - 1) - s = s[start:start+itemsize] - - complex_data = numpy.fromstring (s, numpy.float32) - de = DataEvent (complex_data) - wx.PostEvent (self.event_receiver, de) - del de - - -class waterfall_window (wx.ScrolledWindow): - def __init__ (self, fftsink, parent, id = -1, - pos = wx.DefaultPosition, size = wx.DefaultSize, - style = wx.DEFAULT_FRAME_STYLE, name = "", report=None, - ref_level = 0, span = 50, ofunc=None, xydfunc=None): - wx.ScrolledWindow.__init__(self, parent, id, pos, size, - style|wx.HSCROLL, name) - self.parent = parent - self.SetCursor(wx.StockCursor(wx.CURSOR_IBEAM)) - self.ref_level = ref_level - self.scale_factor = 256./span - - self.ppsh = 128 # pixels per scroll, horizontal - self.SetScrollbars( self.ppsh, 0, fftsink.fft_size/self.ppsh, 0 ) - - self.fftsink = fftsink - self.size = size - self.report = report - self.ofunc = ofunc - self.xydfunc = xydfunc - - dc1 = wx.MemoryDC() - dc1.SetFont( wx.SMALL_FONT ) - self.h_scale = dc1.GetCharHeight() + 3 - #self.bm_size = ( self.fftsink.fft_size, self.size[1] - self.h_scale ) - self.im_size = ( self.fftsink.fft_size, self.size[1] - self.h_scale ) - #self.bm = wx.EmptyBitmap( self.bm_size[0], self.bm_size[1], -1) - self.im = wx.EmptyImage( self.im_size[0], self.im_size[1], True ) - self.im_cur = 0 - - self.baseband_freq = None - - self.make_pens() - - wx.EVT_PAINT( self, self.OnPaint ) - wx.EVT_CLOSE (self, self.on_close_window) - #wx.EVT_LEFT_UP(self, self.on_left_up) - #wx.EVT_LEFT_DOWN(self, self.on_left_down) - EVT_DATA_EVENT (self, self.set_data) - - self.build_popup_menu() - - wx.EVT_CLOSE (self, self.on_close_window) - self.Bind(wx.EVT_RIGHT_UP, self.on_right_click) - self.Bind(wx.EVT_MOTION, self.on_motion) - - self.down_pos = None - - self.input_watcher = input_watcher(fftsink.msgq, fftsink.fft_size, self) - - def on_close_window (self, event): - self.keep_running = False - - def on_left_down( self, evt ): - self.down_pos = evt.GetPosition() - self.down_time = evt.GetTimestamp() - - def on_left_up( self, evt ): - if self.down_pos: - dt = ( evt.GetTimestamp() - self.down_time )/1000. - pph = self.fftsink.fft_size/float(self.fftsink.sample_rate) - dx = evt.GetPosition()[0] - self.down_pos[0] - if dx != 0: - rt = pph/dx - else: - rt = 0 - t = 'Down time: %f Delta f: %f Period: %f' % ( dt, dx/pph, rt ) - print t - if self.report: - self.report(t) - - def on_motion(self, event): - if self.xydfunc: - pos = event.GetPosition() - self.xydfunc(pos) - - - def const_list(self,const,len): - return [const] * len - - def make_colormap(self): - r = [] - r.extend(self.const_list(0,96)) - r.extend(range(0,255,4)) - r.extend(self.const_list(255,64)) - r.extend(range(255,128,-4)) - - g = [] - g.extend(self.const_list(0,32)) - g.extend(range(0,255,4)) - g.extend(self.const_list(255,64)) - g.extend(range(255,0,-4)) - g.extend(self.const_list(0,32)) - - b = range(128,255,4) - b.extend(self.const_list(255,64)) - b.extend(range(255,0,-4)) - b.extend(self.const_list(0,96)) - return (r,g,b) - - def make_pens(self): - (r,g,b) = self.make_colormap() - self.rgb = numpy.transpose( numpy.array( (r,g,b) ).astype(numpy.int8) ) - - def OnPaint(self, event): - dc = wx.BufferedPaintDC(self) - self.DoDrawing( dc ) - - def DoDrawing(self,dc): - w, h = self.GetClientSizeTuple() - w = min( w, self.fftsink.fft_size ) - if w <= 0: - return - - if dc is None: - dc = wx.BufferedDC( wx.ClientDC(self), (w,h) ) - - dc.SetBackground( wx.Brush( self.GetBackgroundColour(), wx.SOLID ) ) - dc.Clear() - - x, y = self.GetViewStart() - x *= self.ppsh - - ih = min( h - self.h_scale, self.im_size[1] - self.im_cur ) - r = wx.Rect( x, self.im_cur, w, ih ) - bm = wx.BitmapFromImage( self.im.GetSubImage(r) ) - dc.DrawBitmap( bm, 0, self.h_scale ) - rem = min( self.im_size[1] - ih, h - ih - self.h_scale ) - if( rem > 0 ): - r = wx.Rect( x, 0, w, rem ) - bm = wx.BitmapFromImage( self.im.GetSubImage(r) ) - dc.DrawBitmap( bm, 0, ih + self.h_scale ) - - # Draw axis - if self.baseband_freq != self.fftsink.baseband_freq: - self.baseband_freq = self.fftsink.baseband_freq - t = self.fftsink.sample_rate*w/float(self.fftsink.fft_size) - self.ax_spec = axis_design( self.baseband_freq - t/2, - self.baseband_freq + t/2, 7 ) - dc.SetFont( wx.SMALL_FONT ) - fo = self.baseband_freq - po = self.fftsink.fft_size/2 - pph = self.fftsink.fft_size/float(self.fftsink.sample_rate) - f = math.floor((fo-po/pph)/self.ax_spec[1])*self.ax_spec[1] - while True: - t = po + ( f - fo )*pph - s = str( f*self.ax_spec[3] ) - e = dc.GetTextExtent( s ) - if t - e[1]/2 >= x + w: - break - dc.DrawText( s, t - x - e[0]/2, 0 ) - dc.DrawLine( t - x, e[1] - 1, t - x, self.h_scale ) - dt = self.ax_spec[1]/self.ax_spec[2]*pph - for i in range(self.ax_spec[2]-1): - t += dt - if t >= x + w: - break - dc.DrawLine( t - x, e[1] + 1, t - x, self.h_scale ) - f += self.ax_spec[1] - - def const_list(self,const,len): - a = [const] - for i in range(1,len): - a.append(const) - return a - - def make_colormap(self): - r = [] - r.extend(self.const_list(0,96)) - r.extend(range(0,255,4)) - r.extend(self.const_list(255,64)) - r.extend(range(255,128,-4)) - - g = [] - g.extend(self.const_list(0,32)) - g.extend(range(0,255,4)) - g.extend(self.const_list(255,64)) - g.extend(range(255,0,-4)) - g.extend(self.const_list(0,32)) - - b = range(128,255,4) - b.extend(self.const_list(255,64)) - b.extend(range(255,0,-4)) - b.extend(self.const_list(0,96)) - return (r,g,b) - - def set_data (self, evt): - dB = evt.data - L = len (dB) - - if self.ofunc != None: - self.ofunc(evt.data, L) - #dc1 = wx.MemoryDC() - #dc1.SelectObject(self.bm) - - # Scroll existing bitmap - if 1: - #dc1.Blit(0,1,self.bm_size[0],self.bm_size[1]-1,dc1,0,0, - # wx.COPY,False,-1,-1) - pass - else: - for i in range( self.bm_size[1]-1, 0, -1 ): - dc1.Blit( 0, i, self.bm_size[0], 1, dc1, 0, i-1 ) - - x = max(abs(self.fftsink.sample_rate), abs(self.fftsink.baseband_freq)) - if x >= 1e9: - sf = 1e-9 - units = "GHz" - elif x >= 1e6: - sf = 1e-6 - units = "MHz" - else: - sf = 1e-3 - units = "kHz" - - - if self.fftsink.input_is_real: # only plot 1/2 the points - d_max = L/2 - p_width = 2 - else: - d_max = L/2 - p_width = 1 - - scale_factor = self.scale_factor - dB -= self.ref_level - dB *= scale_factor - dB = dB.astype(numpy.int_).clip( min=0, max=255 ) - if self.fftsink.input_is_real: # real fft - dB = numpy.array( ( dB[0:d_max][::-1], dB[0:d_max] ) ) - else: # complex fft - dB = numpy.concatenate( ( dB[d_max:L], dB[0:d_max] ) ) - - dB = self.rgb[dB] - img = wx.ImageFromData( L, 1, dB.ravel().tostring() ) - #bm = wx.BitmapFromImage( img ) - #dc1.DrawBitmap( bm, 0, 0 ) - ibuf = self.im.GetDataBuffer() - self.im_cur -= 1 - if self.im_cur < 0: - self.im_cur = self.im_size[1] - 1 - start = 3*self.im_cur*self.im_size[0] - ibuf[start:start+3*self.im_size[0]] = img.GetData() - - #del dc1 - self.DoDrawing(None) - - def on_average(self, evt): - # print "on_average" - self.fftsink.set_average(evt.IsChecked()) - - def on_right_click(self, event): - menu = self.popup_menu - self.PopupMenu(menu, event.GetPosition()) - - - def build_popup_menu(self): - id_ref_gain = wx.NewId() - self.Bind( wx.EVT_MENU, self.on_ref_gain, id=id_ref_gain ) - - # make a menu - menu = wx.Menu() - self.popup_menu = menu - menu.Append( id_ref_gain, "Ref Level and Gain" ) - self.rg_dialog = None - - self.checkmarks = { - #self.id_average : lambda : self.fftsink.average - } - - def on_ref_gain( self, evt ): - if self.rg_dialog == None: - self.rg_dialog = rg_dialog( self.parent, self.set_ref_gain, - ref=self.ref_level, - span=256./self.scale_factor ) - self.rg_dialog.Show( True ) - - def set_ref_gain( self, ref, span ): - self.ref_level = ref - self.scale_factor = 256/span - -class rg_dialog( wx.Dialog ): - def __init__( self, parent, set_function, ref=0, span=256./5. ): - wx.Dialog.__init__( self, parent, -1, "Waterfall Settings" ) - self.set_function = set_function - #status_bar = wx.StatusBar( self, -1 ) - - d_sizer = wx.BoxSizer( wx.VERTICAL ) # dialog sizer - f_sizer = wx.BoxSizer( wx.VERTICAL ) # form sizer - vs = 10 - - #f_sizer.Add( fn_sizer, 0, flag=wx.TOP, border=10 ) - - h_sizer = wx.BoxSizer( wx.HORIZONTAL ) - self.ref = tab_item( self, "Ref Level:", 4, "dB" ) - self.ref.ctrl.SetValue( "%d" % ref ) - h_sizer.Add((0,0),1) - h_sizer.Add( self.ref, 0 ) - h_sizer.Add((0,0),1) - self.span = tab_item( self, "Range:", 4, "dB" ) - self.span.ctrl.SetValue( "%d" % span ) - h_sizer.Add( self.span, 0 ) - h_sizer.Add((0,0),1) - f_sizer.Add( h_sizer, 0, flag=wx.TOP|wx.EXPAND, border=vs ) - - d_sizer.Add((0,0),1) - d_sizer.Add( f_sizer, 0, flag=wx.ALIGN_CENTER_HORIZONTAL|wx.EXPAND ) - d_sizer.Add((0,0),1) - d_sizer.Add((0,0),1) - - button_sizer = wx.BoxSizer( wx.HORIZONTAL ) - apply_button = wx.Button( self, -1, "Apply" ) - apply_button.Bind( wx.EVT_BUTTON, self.apply_evt ) - cancel_button = wx.Button( self, -1, "Cancel" ) - cancel_button.Bind( wx.EVT_BUTTON, self.cancel_evt ) - ok_button = wx.Button( self, -1, "OK" ) - ok_button.Bind( wx.EVT_BUTTON, self.ok_evt ) - button_sizer.Add((0,0),1) - button_sizer.Add( apply_button, 0, - flag=wx.ALIGN_CENTER_HORIZONTAL ) - button_sizer.Add((0,0),1) - button_sizer.Add( cancel_button, 0, - flag=wx.ALIGN_CENTER_HORIZONTAL ) - button_sizer.Add((0,0),1) - button_sizer.Add( ok_button, 0, - flag=wx.ALIGN_CENTER_HORIZONTAL ) - button_sizer.Add((0,0),1) - d_sizer.Add( button_sizer, 0, - flag=wx.EXPAND|wx.ALIGN_CENTER|wx.BOTTOM, border=30 ) - self.SetSizer( d_sizer ) - - def apply_evt( self, evt ): - self.do_apply() - - def cancel_evt( self, evt ): - self.Show( False ) - - def ok_evt( self, evt ): - self.do_apply() - self.Show( False ) - - def do_apply( self ): - r = float( self.ref.ctrl.GetValue() ) - g = float( self.span.ctrl.GetValue() ) - self.set_function( r, g ) - -def next_up(v, seq): - """ - Return the first item in seq that is > v. - """ - for s in seq: - if s > v: - return s - return v - -def next_down(v, seq): - """ - Return the last item in seq that is < v. - """ - rseq = list(seq[:]) - rseq.reverse() - - for s in rseq: - if s < v: - return s - return v - -# One of many copies that should be consolidated . . . -def tab_item( parent, label, chars, units, style=wx.TE_RIGHT, value="" ): - s = wx.BoxSizer( wx.HORIZONTAL ) - s.Add( wx.StaticText( parent, -1, label ), 0, - flag=wx.ALIGN_CENTER_VERTICAL ) - s.ctrl = wx.TextCtrl( parent, -1, style=style, value=value ) - s.ctrl.SetMinSize( ( (1.00+chars)*s.ctrl.GetCharWidth(), - 1.25*s.ctrl.GetCharHeight() ) ) - s.Add( s.ctrl, -1, flag=wx.LEFT, border=3 ) - s.Add( wx.StaticText( parent, -1, units ), 0, - flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT, border=1 ) - return s - - -# ---------------------------------------------------------------- -# Standalone test app -# ---------------------------------------------------------------- - -class test_app_flow_graph (stdgui2.std_top_block): - def __init__(self, frame, panel, vbox, argv): - stdgui2.std_top_block.__init__ (self, frame, panel, vbox, argv) - - fft_size = 512 - - # build our flow graph - input_rate = 20.000e3 - - # Generate a complex sinusoid - src1 = gr.sig_source_c (input_rate, gr.GR_SIN_WAVE, 5.75e3, 1000) - #src1 = gr.sig_source_c (input_rate, gr.GR_CONST_WAVE, 5.75e3, 1000) - - # We add these throttle blocks so that this demo doesn't - # suck down all the CPU available. Normally you wouldn't use these. - thr1 = gr.throttle(gr.sizeof_gr_complex, input_rate) - - sink1 = waterfall_sink_c (panel, title="Complex Data", - fft_size=fft_size, - sample_rate=input_rate, baseband_freq=0, - size=(600,144) ) - vbox.Add (sink1.win, 1, wx.EXPAND) - self.connect (src1, thr1, sink1) - - # generate a real sinusoid - src2 = gr.sig_source_f (input_rate, gr.GR_SIN_WAVE, 5.75e3, 1000) - #src2 = gr.sig_source_f (input_rate, gr.GR_CONST_WAVE, 5.75e3, 1000) - thr2 = gr.throttle(gr.sizeof_float, input_rate) - sink2 = waterfall_sink_f (panel, title="Real Data", fft_size=fft_size, - sample_rate=input_rate, baseband_freq=0) - vbox.Add (sink2.win, 1, wx.EXPAND) - self.connect (src2, thr2, sink2) - -def main (): - app = stdgui2.stdapp (test_app_flow_graph, - "Waterfall Sink Test App") - app.MainLoop () - -if __name__ == '__main__': - main () diff --git a/gr-radio-astronomy/src/python/run_tests.in b/gr-radio-astronomy/src/python/run_tests.in deleted file mode 100644 index c382145a6..000000000 --- a/gr-radio-astronomy/src/python/run_tests.in +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -# 1st parameter is absolute path to component source directory -# 2nd parameter is absolute path to component build directory -# 3rd parameter is path to Python QA directory - -@top_builddir@/run_tests.sh \ - @abs_top_srcdir@/gr-radio-astronomy \ - @abs_top_builddir@/gr-radio-astronomy \ - @srcdir@ diff --git a/gr-radio-astronomy/src/python/usrp_psr_receiver.help b/gr-radio-astronomy/src/python/usrp_psr_receiver.help deleted file mode 100644 index 5801f3fbb..000000000 --- a/gr-radio-astronomy/src/python/usrp_psr_receiver.help +++ /dev/null @@ -1,111 +0,0 @@ -This program is used to analyse pulsars of known parameters. It contains - both a post-detector spectral display, and a "pulse profile" display. - It has a built-in de-dispersion filter that will work up to DM=100 for - 21cm observing, and up to DM=5 for 327Mhz observing. - -The program takes the following options: - - --rx-subdev-spec which USRP Rx side? A or B - - --decim USRP decimation rate use either 64 or 128 - - --freq USRP daughtercard frequency - - --observing Actual observing frequency (default is to use the - setting for --freq) - - --avg Averaging setting for spectral display--higher numbers - equal more averaging. 25 to 40 is typical. - - --favg Pulse folding averaging. 2 to 5 is typical. - - --gain USRP daughtercard gain control - - --reflevel Reference level on pulse profile display - - --lowest Lowest spectral bin that is considered valid, in Hz - - --longitude Observer longitude: West is negative - - --latitude Observer latitude: South is negative - - --fft_size Size of FFT for post-detector spectrum: default is 1024 - - --threshold Threshold (dB) to be considered a spectral "peak" - This is relative to the average spectral level - - --lowpass Low pass frequency for post-detector spectral display - 20-100 is typical - - --prefix Filename prefix to use for recording files - Default is ./ - - --pulsefreq The frequency of the expected pulses - For sentimental reasons, this defaults to 0.748Hz - - --dm The DM - - --doppler The doppler shift, as a ratio - - --divbase The base of the Y/Div menu in pulsar display - - --division The initial Y/Div in pulsar display - -DM, Doppler, Gain, Frequency, and the averaging parameters can all be - changed using the GUI at runtime. - -If latitude and longitude are set correctly, and the system time is - correct, then the current LMST is displayed below the frequency - input, updated once per second. - -Moving the mouse in the post-detector spectrum display shows you that - point in the post-detector spectrum, both frequency and signal level. - -The post-detector spectrum is analysed, with results shown below - "Best freq". It shows the spectral peaks, and computes their relationship. - It shows the harmonic compliance among the peaks, as well as the average - peak-to-peak distance. - - -Here's a complete example for observing a pulsar with a frequency of - 1.35Hz, at 431.5Mhz, using an IF of 10.7Mhz, and a DM of 12.431, using - 1Mhz observing bandwidth: - -./usrp_psr_receiver.py --freq 10.7e6 --decim 64 --dm 12.431 --avg 35 \ - --pulsefreq 1.35 --fft_size 2048 --lowest 1.00 --gain 75 --threshold 11.5 \ - --observing 431.5e6 --reflevel 200 --division 100 --divbase 10 --favg 3 \ - --lowpass 20 --longitude -76.02 --latitude 44.95 - -Since the observed pulsar is at 1.35Hz, a lowpass cutoff for the - post-detector spectral display of 20Hz will be adequate. We - tell the spectral analyser to use a threshold of 11.5dB above - average when analysing spectral data, and set the epoch folder - averager (pulse profile display) to use an average from 3 samples. - Notice that our actual USRP/Daughtercard frequency is 10.7Mhz, while - our observing frequency is 431.5Mhz--this is important in order for - the DM de-dispersion calculations to be correct. We also set our - latitude and longitude, so that logfiles and the LMST display - will have the correct LMST in them. - -The entire complex baseband can be recorded, if the "Recording baseband" - button is pressed. Filenames are generated dynamically, and a header - file is produced giving observation parameters. The baseband data are - recorded as octet pairs: one for I and one for Q. Pressing the button again - turns off baseband recording. This baseband is "raw", so it will - not have been de-dispersed. The data rate will be whatever the - USRP was programmed to at the time (based on --decim). - - The files are: YYYYMMDDHHMM.pdat and YYYYMMDDHHMM.phdr - - The .phdr file contains ASCII header information describing the - contents of the .pdat file. - -Similarly the raw, pre-folded, band-limited post-detector "audio" data can be - recorded using the "Record Pulses" button. The data rate for these is - currently 20Khz, recorded as short integers. Just like baseband recording, - pressing the button again turns off pulse recording. - - The files are: YYYYMMDDHHMM.padat and YYMMDDHHMM.pahdr - - The .pahdr file is ascii text providing information about the contents - of the corresponding .padat file. diff --git a/gr-radio-astronomy/src/python/usrp_psr_receiver.py b/gr-radio-astronomy/src/python/usrp_psr_receiver.py deleted file mode 100755 index 6ce4325a2..000000000 --- a/gr-radio-astronomy/src/python/usrp_psr_receiver.py +++ /dev/null @@ -1,1096 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2004,2005,2007 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, blks2, audio -from usrpm import usrp_dbid -from gnuradio import usrp, optfir -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from gnuradio.wxgui import stdgui2, ra_fftsink, ra_stripchartsink, form, slider -from optparse import OptionParser -import wx -import sys -import Numeric -import numpy.fft -import ephem -import time -import os -import math - - -class app_flow_graph(stdgui2.std_top_block): - 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) - - - def _set_status_msg(self, msg): - self.frame.GetStatusBar().SetStatusText(msg, 0) - - def _build_gui(self, vbox): - - def _form_set_freq(kv): - return self.set_freq(kv['freq']) - - def _form_set_dm(kv): - return self.set_dm(kv['DM']) - - def _form_set_doppler(kv): - return self.set_doppler(kv['Doppler']) - - # Position the FFT or Waterfall - vbox.Add(self.scope.win, 5, wx.EXPAND) - vbox.Add(self.chart.win, 5, wx.EXPAND) - - # add control area at the bottom - self.myform = myform = form.form() - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add((7,0), 0, wx.EXPAND) - vbox1 = wx.BoxSizer(wx.VERTICAL) - myform['freq'] = form.float_field( - parent=self.panel, sizer=vbox1, label="Center freq", weight=1, - callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg)) - - vbox1.Add((3,0), 0, 0) - - # To show current Local Mean Sidereal Time - myform['lmst_high'] = form.static_text_field( - parent=self.panel, sizer=vbox1, label="Current LMST", weight=1) - vbox1.Add((3,0), 0, 0) - - # To show current spectral cursor data - myform['spec_data'] = form.static_text_field( - parent=self.panel, sizer=vbox1, label="Pulse Freq", weight=1) - vbox1.Add((3,0), 0, 0) - - # To show best pulses found in FFT output - myform['best_pulse'] = form.static_text_field( - parent=self.panel, sizer=vbox1, label="Best freq", weight=1) - vbox1.Add((3,0), 0, 0) - - vboxBogus = wx.BoxSizer(wx.VERTICAL) - vboxBogus.Add ((2,0), 0, wx.EXPAND) - vbox2 = wx.BoxSizer(wx.VERTICAL) - g = self.subdev.gain_range() - myform['gain'] = form.slider_field(parent=self.panel, sizer=vbox2, label="RF Gain", - weight=1, - min=int(g[0]), max=int(g[1]), - callback=self.set_gain) - - vbox2.Add((6,0), 0, 0) - myform['average'] = form.slider_field(parent=self.panel, sizer=vbox2, - label="Spectral Averaging", weight=1, min=1, max=200, callback=self.set_averaging) - vbox2.Add((6,0), 0, 0) - myform['foldavg'] = form.slider_field(parent=self.panel, sizer=vbox2, - label="Folder Averaging", weight=1, min=1, max=20, callback=self.set_folder_averaging) - vbox2.Add((6,0), 0, 0) - #myform['volume'] = form.quantized_slider_field(parent=self.panel, sizer=vbox2, - #label="Audio Volume", weight=1, range=(-20, 0, 0.5), callback=self.set_volume) - #vbox2.Add((6,0), 0, 0) - myform['DM'] = form.float_field( - parent=self.panel, sizer=vbox2, label="DM", weight=1, - callback=myform.check_input_and_call(_form_set_dm)) - vbox2.Add((6,0), 0, 0) - myform['Doppler'] = form.float_field( - parent=self.panel, sizer=vbox2, label="Doppler", weight=1, - callback=myform.check_input_and_call(_form_set_doppler)) - vbox2.Add((6,0), 0, 0) - - - # Baseband recording control - buttonbox = wx.BoxSizer(wx.HORIZONTAL) - self.record_control = form.button_with_callback(self.panel, - label="Recording baseband: Off ", - callback=self.toggle_recording) - self.record_pulse_control = form.button_with_callback(self.panel, - label="Recording pulses: Off ", - callback=self.toggle_pulse_recording) - - buttonbox.Add(self.record_control, 0, wx.CENTER) - buttonbox.Add(self.record_pulse_control, 0, wx.CENTER) - vbox.Add(buttonbox, 0, wx.CENTER) - hbox.Add(vbox1, 0, 0) - hbox.Add(vboxBogus, 0, 0) - hbox.Add(vbox2, wx.ALIGN_RIGHT, 0) - vbox.Add(hbox, 0, wx.EXPAND) - - self._build_subpanel(vbox) - - self.lmst_timer = wx.PyTimer(self.lmst_timeout) - self.lmst_timeout() - - - def _build_subpanel(self, vbox_arg): - # build a secondary information panel (sometimes hidden) - - # FIXME figure out how to have this be a subpanel that is always - # created, but has its visibility controlled by foo.Show(True/False) - - if not(self.show_debug_info): - return - - panel = self.panel - vbox = vbox_arg - myform = self.myform - - #panel = wx.Panel(self.panel, -1) - #vbox = wx.BoxSizer(wx.VERTICAL) - - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add((5,0), 0) - myform['decim'] = form.static_float_field( - parent=panel, sizer=hbox, label="Decim") - - hbox.Add((5,0), 1) - myform['fs@usb'] = form.static_float_field( - parent=panel, sizer=hbox, label="Fs@USB") - - hbox.Add((5,0), 1) - myform['dbname'] = form.static_text_field( - parent=panel, sizer=hbox) - - hbox.Add((5,0), 1) - myform['baseband'] = form.static_float_field( - parent=panel, sizer=hbox, label="Analog BB") - - hbox.Add((5,0), 1) - myform['ddc'] = form.static_float_field( - parent=panel, sizer=hbox, label="DDC") - - hbox.Add((5,0), 0) - vbox.Add(hbox, 0, wx.EXPAND) - - - - def set_freq(self, target_freq): - """ - Set the center frequency we're interested in. - - @param target_freq: frequency in Hz - @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital down converter. - """ - r = usrp.tune(self.u, 0, self.subdev, target_freq) - - if r: - self.myform['freq'].set_value(target_freq) # update displayed value - self.myform['baseband'].set_value(r.baseband_freq) - self.myform['ddc'].set_value(r.dxc_freq) - # Adjust self.frequency, and self.observing_freq - # We pick up the difference between the current self.frequency - # and the just-programmed one, and use this to adjust - # self.observing_freq. We have to do it this way to - # make the dedispersion filtering work out properly. - delta = target_freq - self.frequency - self.frequency = target_freq - self.observing_freq += delta - - # Now that we're adjusted, compute a new dispfilter, and - # set the taps for the FFT filter. - ntaps = self.compute_disp_ntaps(self.dm, self.bw, self.observing_freq) - self.disp_taps = Numeric.zeros(ntaps, Numeric.Complex64) - self.compute_dispfilter(self.dm,self.doppler,self.bw, - self.observing_freq) - self.dispfilt.set_taps(self.disp_taps) - - return True - - return False - - # Callback for gain-setting slider - def set_gain(self, gain): - self.myform['gain'].set_value(gain) # update displayed value - self.subdev.set_gain(gain) - - - #def set_volume(self, vol): - #self.myform['volume'].set_value(vol) - #self.volume.set_k((10**(vol/10))/8192) - - # Callback for spectral-averaging slider - def set_averaging(self, avval): - self.myform['average'].set_value(avval) - self.scope.set_avg_alpha(1.0/(avval)) - self.scope.set_average(True) - - def set_folder_averaging(self, avval): - self.myform['foldavg'].set_value(avval) - self.folder_iir.set_taps(1.0/avval) - - # Timer callback to update LMST display - def lmst_timeout(self): - self.locality.date = ephem.now() - sidtime = self.locality.sidereal_time() - self.myform['lmst_high'].set_value(str(ephem.hours(sidtime))) - - # - # Turn recording on/off - # Called-back by "Recording" button - # - def toggle_recording(self): - # Pick up current LMST - self.locality.date = ephem.now() - sidtime = self.locality.sidereal_time() - - # Pick up localtime, for generating filenames - foo = time.localtime() - - # Generate filenames for both data and header file - filename = "%04d%02d%02d%02d%02d.pdat" % (foo.tm_year, foo.tm_mon, - foo.tm_mday, foo.tm_hour, foo.tm_min) - hdrfilename = "%04d%02d%02d%02d%02d.phdr" % (foo.tm_year, foo.tm_mon, - foo.tm_mday, foo.tm_hour, foo.tm_min) - - # Current recording? Flip state - if (self.recording_state == True): - self.recording_state = False - self.record_control.SetLabel("Recording baseband: Off ") - self.recording.close() - # Not recording? - else: - self.recording_state = True - self.record_control.SetLabel("Recording baseband to: "+filename) - - # Cause gr_file_sink object to accept new filename - # note use of self.prefix--filename prefix from - # command line (defaults to ./) - # - self.recording.open (self.prefix+filename) - - # - # We open the header file as a regular file, write header data, - # then close - hdrf = open(self.prefix+hdrfilename, "w") - hdrf.write("receiver center frequency: "+str(self.frequency)+"\n") - hdrf.write("observing frequency: "+str(self.observing_freq)+"\n") - hdrf.write("DM: "+str(self.dm)+"\n") - hdrf.write("doppler: "+str(self.doppler)+"\n") - - hdrf.write("sidereal: "+str(ephem.hours(sidtime))+"\n") - hdrf.write("bandwidth: "+str(self.u.adc_freq() / self.u.decim_rate())+"\n") - hdrf.write("sample type: complex_char\n") - hdrf.write("sample size: "+str(gr.sizeof_char*2)+"\n") - hdrf.close() - # - # Turn recording on/off - # Called-back by "Recording" button - # - def toggle_pulse_recording(self): - # Pick up current LMST - self.locality.date = ephem.now() - sidtime = self.locality.sidereal_time() - - # Pick up localtime, for generating filenames - foo = time.localtime() - - # Generate filenames for both data and header file - filename = "%04d%02d%02d%02d%02d.padat" % (foo.tm_year, foo.tm_mon, - foo.tm_mday, foo.tm_hour, foo.tm_min) - hdrfilename = "%04d%02d%02d%02d%02d.pahdr" % (foo.tm_year, foo.tm_mon, - foo.tm_mday, foo.tm_hour, foo.tm_min) - - # Current recording? Flip state - if (self.pulse_recording_state == True): - self.pulse_recording_state = False - self.record_pulse_control.SetLabel("Recording pulses: Off ") - self.pulse_recording.close() - # Not recording? - else: - self.pulse_recording_state = True - self.record_pulse_control.SetLabel("Recording pulses to: "+filename) - - # Cause gr_file_sink object to accept new filename - # note use of self.prefix--filename prefix from - # command line (defaults to ./) - # - self.pulse_recording.open (self.prefix+filename) - - # - # We open the header file as a regular file, write header data, - # then close - hdrf = open(self.prefix+hdrfilename, "w") - hdrf.write("receiver center frequency: "+str(self.frequency)+"\n") - hdrf.write("observing frequency: "+str(self.observing_freq)+"\n") - hdrf.write("DM: "+str(self.dm)+"\n") - hdrf.write("doppler: "+str(self.doppler)+"\n") - hdrf.write("pulse rate: "+str(self.pulse_freq)+"\n") - hdrf.write("pulse sps: "+str(self.pulse_freq*self.folding)+"\n") - hdrf.write("file sps: "+str(self.folder_input_rate)+"\n") - - hdrf.write("sidereal: "+str(ephem.hours(sidtime))+"\n") - hdrf.write("bandwidth: "+str(self.u.adc_freq() / self.u.decim_rate())+"\n") - hdrf.write("sample type: short\n") - hdrf.write("sample size: 1\n") - hdrf.close() - - # We get called at startup, and whenever the GUI "Set Folding params" - # button is pressed - # - def set_folding_params(self): - if (self.pulse_freq <= 0): - return - - # Compute required sample rate - self.sample_rate = int(self.pulse_freq*self.folding) - - # And the implied decimation rate - required_decimation = int(self.folder_input_rate / self.sample_rate) - - # We also compute a new FFT comb filter, based on the expected - # spectral profile of our pulse parameters - # - # FFT-based comb filter - # - N_COMB_TAPS=int(self.sample_rate*4) - if N_COMB_TAPS > 2000: - N_COMB_TAPS = 2000 - self.folder_comb_taps = Numeric.zeros(N_COMB_TAPS,Numeric.Complex64) - fincr = (self.sample_rate)/float(N_COMB_TAPS) - for i in range(0,len(self.folder_comb_taps)): - self.folder_comb_taps[i] = complex(0.0, 0.0) - - freq = 0.0 - harmonics = [1.0,2.0,3.0,4.0,5.0,6.0,7.0] - for i in range(0,len(self.folder_comb_taps)/2): - for j in range(0,len(harmonics)): - if abs(freq - harmonics[j]*self.pulse_freq) <= fincr: - self.folder_comb_taps[i] = complex(4.0, 0.0) - if harmonics[j] == 1.0: - self.folder_comb_taps[i] = complex(8.0, 0.0) - freq += fincr - - if self.enable_comb_filter == True: - # Set the just-computed FFT comb filter taps - self.folder_comb.set_taps(self.folder_comb_taps) - - # And compute a new decimated bandpass filter, to go in front - # of the comb. Primary function is to decimate and filter down - # to an exact-ish multiple of the target pulse rate - # - self.folding_taps = gr.firdes_band_pass (1.0, self.folder_input_rate, - 0.10, self.sample_rate/2, 10, - gr.firdes.WIN_HAMMING) - - # Set the computed taps for the bandpass/decimate filter - self.folder_bandpass.set_taps (self.folding_taps) - # - # Record a spectral "hit" of a possible pulsar spectral profile - # - def record_hit(self,hits, hcavg, hcmax): - # Pick up current LMST - self.locality.date = ephem.now() - sidtime = self.locality.sidereal_time() - - # Pick up localtime, for generating filenames - foo = time.localtime() - - # Generate filenames for both data and header file - hitfilename = "%04d%02d%02d%02d.phit" % (foo.tm_year, foo.tm_mon, - foo.tm_mday, foo.tm_hour) - - hitf = open(self.prefix+hitfilename, "a") - hitf.write("receiver center frequency: "+str(self.frequency)+"\n") - hitf.write("observing frequency: "+str(self.observing_freq)+"\n") - hitf.write("DM: "+str(self.dm)+"\n") - hitf.write("doppler: "+str(self.doppler)+"\n") - - hitf.write("sidereal: "+str(ephem.hours(sidtime))+"\n") - hitf.write("bandwidth: "+str(self.u.adc_freq() / self.u.decim_rate())+"\n") - hitf.write("spectral peaks: "+str(hits)+"\n") - hitf.write("HCM: "+str(hcavg)+" "+str(hcmax)+"\n") - hitf.close() - - # This is a callback used by ra_fftsink.py (passed on creation of - # ra_fftsink) - # Whenever the user moves the cursor within the FFT display, this - # shows the coordinate data - # - def xydfunc(self,xyv): - s = "%.6fHz\n%.3fdB" % (xyv[0], xyv[1]) - if self.lowpass >= 500: - s = "%.6fHz\n%.3fdB" % (xyv[0]*1000, xyv[1]) - - self.myform['spec_data'].set_value(s) - - # This is another callback used by ra_fftsink.py (passed on creation - # of ra_fftsink). We pass this as our "calibrator" function, but - # we create interesting side-effects in the GUI. - # - # This function finds peaks in the FFT output data, and reports - # on them through the "Best" text object in the GUI - # It also computes the Harmonic Compliance Measure (HCM), and displays - # that also. - # - def pulsarfunc(self,d,l): - x = range(0,l) - incr = float(self.lowpass)/float(l) - incr = incr * 2.0 - bestdb = -50.0 - bestfreq = 0.0 - avg = 0 - dcnt = 0 - # - # First, we need to find the average signal level - # - for i in x: - if (i * incr) > self.lowest_freq and (i*incr) < (self.lowpass-2): - avg += d[i] - dcnt += 1 - # Set average signal level - avg /= dcnt - s2=" " - findcnt = 0 - # - # Then we find candidates that are greater than the user-supplied - # threshold. - # - # We try to cluster "hits" whose whole-number frequency is the - # same, and compute an average "hit" frequency. - # - lastint = 0 - hits=[] - intcnt = 0 - freqavg = 0 - for i in x: - freq = i*incr - # If frequency within bounds, and the (dB-avg) value is above our - # threshold - if freq > self.lowest_freq and freq < self.lowpass-2 and (d[i] - avg) > self.threshold: - # If we're finding a new whole-number frequency - if lastint != int(freq): - # Record "center" of this hit, if this is a new hit - if lastint != 0: - s2 += "%5.3fHz " % (freqavg/intcnt) - hits.append(freqavg/intcnt) - findcnt += 1 - lastint = int(freq) - intcnt = 1 - freqavg = freq - else: - intcnt += 1 - freqavg += freq - if (findcnt >= 14): - break - - if intcnt > 1: - s2 += "%5.3fHz " % (freqavg/intcnt) - hits.append(freqavg/intcnt) - - # - # Compute the HCM, by dividing each of the "hits" by each of the - # other hits, and comparing the difference between a "perfect" - # harmonic, and the observed frequency ratio. - # - measure = 0 - max_measure=0 - mcnt = 0 - avg_dist = 0 - acnt = 0 - for i in range(1,len(hits)): - meas = hits[i]/hits[0] - int(hits[i]/hits[0]) - if abs((hits[i]-hits[i-1])-hits[0]) < 0.1: - avg_dist += hits[i]-hits[i-1] - acnt += 1 - if meas > 0.98 and meas < 1.0: - meas = 1.0 - meas - meas *= hits[0] - if meas >= max_measure: - max_measure = meas - measure += meas - mcnt += 1 - if mcnt > 0: - measure /= mcnt - if acnt > 0: - avg_dist /= acnt - if len(hits) > 1: - measure /= mcnt - s3="\nHCM: Avg %5.3fHz(%d) Max %5.3fHz Dist %5.3fHz(%d)" % (measure,mcnt,max_measure, avg_dist, acnt) - if max_measure < 0.5 and len(hits) >= 2: - self.record_hit(hits, measure, max_measure) - self.avg_dist = avg_dist - else: - s3="\nHCM: --" - s4="\nAvg dB: %4.2f" % avg - self.myform['best_pulse'].set_value("("+s2+")"+s3+s4) - - # Since we are nominally a calibrator function for ra_fftsink, we - # simply return what they sent us, untouched. A "real" calibrator - # function could monkey with the data before returning it to the - # FFT display function. - return(d) - - # - # Callback for the "DM" gui object - # - # We call compute_dispfilter() as appropriate to compute a new filter, - # and then set that new filter into self.dispfilt. - # - def set_dm(self,dm): - self.dm = dm - - ntaps = self.compute_disp_ntaps (self.dm, self.bw, self.observing_freq) - self.disp_taps = Numeric.zeros(ntaps, Numeric.Complex64) - self.compute_dispfilter(self.dm,self.doppler,self.bw,self.observing_freq) - self.dispfilt.set_taps(self.disp_taps) - self.myform['DM'].set_value(dm) - return(dm) - - # - # Callback for the "Doppler" gui object - # - # We call compute_dispfilter() as appropriate to compute a new filter, - # and then set that new filter into self.dispfilt. - # - def set_doppler(self,doppler): - self.doppler = doppler - - ntaps = self.compute_disp_ntaps (self.dm, self.bw, self.observing_freq) - self.disp_taps = Numeric.zeros(ntaps, Numeric.Complex64) - self.compute_dispfilter(self.dm,self.doppler,self.bw,self.observing_freq) - self.dispfilt.set_taps(self.disp_taps) - self.myform['Doppler'].set_value(doppler) - return(doppler) - - # - # Compute a de-dispersion filter - # From Hankins, et al, 1975 - # - # This code translated from dedisp_filter.c from Swinburne - # pulsar software repository - # - def compute_dispfilter(self,dm,doppler,bw,centerfreq): - npts = len(self.disp_taps) - tmp = Numeric.zeros(npts, Numeric.Complex64) - M_PI = 3.14159265358 - DM = dm/2.41e-10 - - # - # Because astronomers are a crazy bunch, the "standard" calcultion - # is in Mhz, rather than Hz - # - centerfreq = centerfreq / 1.0e6 - bw = bw / 1.0e6 - - isign = int(bw / abs (bw)) - - # Center frequency may be doppler shifted - cfreq = centerfreq / doppler - - # As well as the bandwidth.. - bandwidth = bw / doppler - - # Bandwidth divided among bins - binwidth = bandwidth / npts - - # Delay is an "extra" parameter, in usecs, and largely - # untested in the Swinburne code. - delay = 0.0 - - # This determines the coefficient of the frequency response curve - # Linear in DM, but quadratic in center frequency - coeff = isign * 2.0*M_PI * DM / (cfreq*cfreq) - - # DC to nyquist/2 - n = 0 - for i in range(0,int(npts/2)): - freq = (n + 0.5) * binwidth - phi = coeff*freq*freq/(cfreq+freq) + (2.0*M_PI*freq*delay) - tmp[i] = complex(math.cos(phi), math.sin(phi)) - n += 1 - - # -nyquist/2 to DC - n = int(npts/2) - n *= -1 - for i in range(int(npts/2),npts): - freq = (n + 0.5) * binwidth - phi = coeff*freq*freq/(cfreq+freq) + (2.0*M_PI*freq*delay) - tmp[i] = complex(math.cos(phi), math.sin(phi)) - n += 1 - - self.disp_taps = numpy.fft.ifft(tmp) - return(self.disp_taps) - - # - # Compute minimum number of taps required in de-dispersion FFT filter - # - def compute_disp_ntaps(self,dm,bw,freq): - # - # Dt calculations are in Mhz, rather than Hz - # crazy astronomers.... - mbw = bw/1.0e6 - mfreq = freq/1.0e6 - - f_lower = mfreq-(mbw/2) - f_upper = mfreq+(mbw/2) - - # Compute smear time - Dt = dm/2.41e-4 * (1.0/(f_lower*f_lower)-1.0/(f_upper*f_upper)) - - # ntaps is now bandwidth*smeartime - # Should be bandwidth*smeartime*2, but the Gnu Radio FFT filter - # already expands it by a factor of 2 - ntaps = bw*Dt - if ntaps < 64: - ntaps = 64 - return(int(ntaps)) - -def main (): - app = stdgui2.stdapp(app_flow_graph, "RADIO ASTRONOMY PULSAR RECEIVER: $Revision$", nstatus=1) - app.MainLoop() - -if __name__ == '__main__': - main () diff --git a/gr-radio-astronomy/src/python/usrp_ra_receiver.help b/gr-radio-astronomy/src/python/usrp_ra_receiver.help deleted file mode 100644 index 45a21e297..000000000 --- a/gr-radio-astronomy/src/python/usrp_ra_receiver.help +++ /dev/null @@ -1,90 +0,0 @@ -This program is used to take spectra and total power measurements. - It records spectral and total-power data to external datalogging - files. - -The program takes the following options: - - --rx-subdev-spec which USRP Rx side? A or B - - --decim USRP decimation rate: 8, 16, 32, and 64 are good - (8Mhz, 4Mhz, 2Mhz, and 1Mhz bandwidth) - - --freq USRP daughtercard frequency - - --observing Actual observing frequency (default is to use the - setting for --freq) - - --avg Averaging setting for spectral display--higher numbers - equal more averaging. 25 to 40 is typical. - - --integ Total power integration time: seconds - - --gain USRP daughtercard gain control - - --reflevel Reference level on pulse profile display - - --longitude Observer longitude: West is negative - - --latitude Observer latitude: South is negative - - --fft_size Size of FFT for post-detector spectrum: default is 1024 - - --prefix Filename prefix to use for data logging files - Default is ./ - - --divbase The base of the Y/Div menu in pulsar display - - --division The initial Y/Div in pulsar display - - --ylabel Y axis label - - --cfunc The function name prefix for the spectral and - calibrator functions - - --waterfall Use waterfall, rather than regular spectral display - NOT TESTED IN THIS APPLICATION - - --stripsize Size of the total-power stripchart, in samples - -There are two windows--a spectral window, and the total-power window. - Moving the cursor around in the spectral window shows you the - corresponding frequency and doppler shift. Left clicking in this - window sets an interference marker, which sets a "zero" in the - interference filter. Use the "clear interference" button to clear this. - -The total power window is updated at a fixed 2Hz rate, and grows from - the left of the display. - -If latitude and longitude are set correctly, and system time is correct, - then the current LMST is displayed, updated once per second. - -Averaging parameters, gain, and frequency can all be set from the GUI using - the appropriate controls. You can also enter the current declination, which - will appear in the datalogging files. This is useful both for mapping, - and housekeeping purposes, particularly when you haven't looked at a datafile - for quite some time. - -There are two datalog files produced by this program: - - YYYYMMDDHH.tpdat Total power data - - The date/time portion of the filename is referred to local time, - rather than UTC or sidereal. - - First field is sidereal time when sample was taken - Second field is total power datum - Third field is declination in decimal degrees - - Samples are written once per second - - YYYYMMDDHH.sdat Spectral data - - The date/time portion of the filename is referred to local time, - rather than UTC or sidereal. - - First field is sidereal time when spectrum was taken - Second field is declination in decimal degrees - Third field is complex spectral data--in the same order that FFTW3 library - places bins: DC to bandwidth/2, followed by -bandwidth/2 to DC. - - Spectral snapshots are written once every 5 seconds diff --git a/gr-radio-astronomy/src/python/usrp_ra_receiver.py b/gr-radio-astronomy/src/python/usrp_ra_receiver.py deleted file mode 100755 index c37355d28..000000000 --- a/gr-radio-astronomy/src/python/usrp_ra_receiver.py +++ /dev/null @@ -1,1384 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2004,2005,2007 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. -# - -from gnuradio import gr, gru -from gnuradio import usrp -from usrpm import usrp_dbid -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from gnuradio.wxgui import stdgui2, ra_fftsink, ra_stripchartsink, ra_waterfallsink, form, slider -from optparse import OptionParser -import wx -import sys -import Numeric -import time -import numpy.fft -import ephem - -class app_flow_graph(stdgui2.std_top_block): - 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("-a", "--avg", type="eng_float", default=1.0, - help="set spectral averaging alpha") - parser.add_option("-i", "--integ", type="eng_float", default=1.0, - help="set integration time") - 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 Total power reference level") - parser.add_option("-y", "--division", type="eng_float", default=0.5, - help="Set Total power Y division size") - 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("-o", "--observing", type="eng_float", default=0.0, - help="Set observing frequency") - parser.add_option("-x", "--ylabel", default="dB", help="Y axis label") - parser.add_option("-z", "--divbase", type="eng_float", default=0.025, help="Y Division increment base") - parser.add_option("-v", "--stripsize", type="eng_float", default=2400, help="Size of stripchart, in 2Hz samples") - parser.add_option("-F", "--fft_size", type="eng_float", default=1024, help="Size of FFT") - parser.add_option("-N", "--decln", type="eng_float", default=999.99, help="Observing declination") - parser.add_option("-X", "--prefix", default="./") - parser.add_option("-M", "--fft_rate", type="eng_float", default=8.0, help="FFT Rate") - parser.add_option("-A", "--calib_coeff", type="eng_float", default=1.0, help="Calibration coefficient") - parser.add_option("-B", "--calib_offset", type="eng_float", default=0.0, help="Calibration coefficient") - parser.add_option("-W", "--waterfall", action="store_true", default=False, help="Use Waterfall FFT display") - parser.add_option("-S", "--setimode", action="store_true", default=False, help="Enable SETI processing of spectral data") - parser.add_option("-K", "--setik", type="eng_float", default=1.5, help="K value for SETI analysis") - parser.add_option("-T", "--setibandwidth", type="eng_float", default=12500, help="Instantaneous SETI observing bandwidth--must be divisor of 250Khz") - parser.add_option("-Q", "--seti_range", type="eng_float", default=1.0e6, help="Total scan width, in Hz for SETI scans") - parser.add_option("-Z", "--dual_mode", action="store_true", - default=False, help="Dual-polarization mode") - parser.add_option("-I", "--interferometer", action="store_true", default=False, help="Interferometer mode") - parser.add_option("-D", "--switch_mode", action="store_true", default=False, help="Dicke Switching mode") - parser.add_option("-P", "--reference_divisor", type="eng_float", default=1.0, help="Reference Divisor") - parser.add_option("-U", "--ref_fifo", default=None) - parser.add_option("-k", "--notch_taps", type="int", default=64, help="Number of notch taps") - parser.add_option("-n", "--notches", action="store_true", - default=False, help="Notch frequencies after all other args") - parser.add_option("-Y", "--interface", default=None) - parser.add_option("-H", "--mac_addr", default=None) - - # Added this documentation - - (options, args) = parser.parse_args() - - self.setimode = options.setimode - self.dual_mode = options.dual_mode - self.interferometer = options.interferometer - self.normal_mode = False - self.switch_mode = options.switch_mode - self.switch_state = 0 - self.reference_divisor = options.reference_divisor - self.ref_fifo = options.ref_fifo - self.usrp2 = False - self.decim = options.decim - self.rx_subdev_spec = options.rx_subdev_spec - - if (options.interface != None and options.mac_addr != None): - self.mac_addr = options.mac_addr - self.interface = options.interface - self.usrp2 = True - - self.NOTCH_TAPS = options.notch_taps - self.notches = Numeric.zeros(self.NOTCH_TAPS,Numeric.Float64) - # Get notch locations - j = 0 - for i in args: - self.notches[j] = float(i) - j = j + 1 - - self.use_notches = options.notches - - if (self.ref_fifo != None): - self.ref_fifo_file = open (self.ref_fifo, "r") - - modecount = 0 - for modes in (self.dual_mode, self.interferometer): - if (modes == True): - modecount = modecount + 1 - - if (modecount > 1): - print "must select only 1 of --dual_mode, or --interferometer" - sys.exit(1) - - self.chartneeded = True - - if (self.setimode == True): - self.chartneeded = False - - if (self.setimode == True and self.interferometer == True): - print "can't pick both --setimode and --interferometer" - sys.exit(1) - - if (self.setimode == True and self.switch_mode == True): - print "can't pick both --setimode and --switch_mode" - sys.exit(1) - - if (self.interferometer == True and self.switch_mode == True): - print "can't pick both --interferometer and --switch_mode" - sys.exit(1) - - if (modecount == 0): - self.normal_mode = True - - self.show_debug_info = True - - # Pick up waterfall option - self.waterfall = options.waterfall - - # SETI mode stuff - self.setimode = options.setimode - self.seticounter = 0 - self.setik = options.setik - self.seti_fft_bandwidth = int(options.setibandwidth) - - # Calculate binwidth - binwidth = self.seti_fft_bandwidth / options.fft_size - - # Use binwidth, and knowledge of likely chirp rates to set reasonable - # values for SETI analysis code. We assume that SETI signals will - # chirp at somewhere between 0.10Hz/sec and 0.25Hz/sec. - # - # upper_limit is the "worst case"--that is, the case for which we have - # to wait the longest to actually see any drift, due to the quantizing - # on FFT bins. - upper_limit = binwidth / 0.10 - self.setitimer = int(upper_limit * 2.00) - self.scanning = True - - # Calculate the CHIRP values based on Hz/sec - self.CHIRP_LOWER = 0.10 * self.setitimer - self.CHIRP_UPPER = 0.25 * self.setitimer - - # Reset hit counters to 0 - self.hitcounter = 0 - self.s1hitcounter = 0 - self.s2hitcounter = 0 - self.avgdelta = 0 - # We scan through 2Mhz of bandwidth around the chosen center freq - self.seti_freq_range = options.seti_range - # Calculate lower edge - self.setifreq_lower = options.freq - (self.seti_freq_range/2) - self.setifreq_current = options.freq - # Calculate upper edge - self.setifreq_upper = options.freq + (self.seti_freq_range/2) - - # Maximum "hits" in a line - self.nhits = 20 - - # Number of lines for analysis - self.nhitlines = 4 - - # We change center frequencies based on nhitlines and setitimer - self.setifreq_timer = self.setitimer * (self.nhitlines * 5) - - # Create actual timer - self.seti_then = time.time() - - # The hits recording array - self.hits_array = Numeric.zeros((self.nhits,self.nhitlines), Numeric.Float64) - self.hit_intensities = Numeric.zeros((self.nhits,self.nhitlines), Numeric.Float64) - # Calibration coefficient and offset - self.calib_coeff = options.calib_coeff - self.calib_offset = options.calib_offset - if self.calib_offset < -750: - self.calib_offset = -750 - if self.calib_offset > 750: - self.calib_offset = 750 - - if self.calib_coeff < 1: - self.calib_coeff = 1 - if self.calib_coeff > 100: - self.calib_coeff = 100 - - self.integ = options.integ - self.avg_alpha = options.avg - self.gain = options.gain - self.decln = options.decln - - # Set initial values for datalogging timed-output - self.continuum_then = time.time() - self.spectral_then = time.time() - - - # build the graph - - self.subdev = [(0, 0), (0,0)] - - # - # If SETI mode, we always run at maximum USRP decimation - # - if (self.setimode): - options.decim = 256 - - if (self.dual_mode == True and self.decim <= 4): - print "Cannot use decim <= 4 with dual_mode" - sys.exit(1) - - self.setup_usrp() - - # Set initial declination - self.decln = options.decln - - input_rate = self.u.adc_freq() / self.u.decim_rate() - self.bw = input_rate - # - # Set prefix for data files - # - self.prefix = options.prefix - - # - # The lower this number, the fewer sample frames are dropped - # in computing the FFT. A sampled approach is taken to - # computing the FFT of the incoming data, which reduces - # sensitivity. Increasing sensitivity inreases CPU loading. - # - self.fft_rate = options.fft_rate - - self.fft_size = int(options.fft_size) - - # This buffer is used to remember the most-recent FFT display - # values. Used later by self.write_spectral_data() to write - # spectral data to datalogging files, and by the SETI analysis - # function. - # - self.fft_outbuf = Numeric.zeros(self.fft_size, Numeric.Float64) - - # - # If SETI mode, only look at seti_fft_bandwidth - # at a time. - # - if (self.setimode): - self.fft_input_rate = self.seti_fft_bandwidth - - # - # Build a decimating bandpass filter - # - self.fft_input_taps = gr.firdes.complex_band_pass (1.0, - input_rate, - -(int(self.fft_input_rate/2)), int(self.fft_input_rate/2), 200, - gr.firdes.WIN_HAMMING, 0) - - # - # Compute required decimation factor - # - decimation = int(input_rate/self.fft_input_rate) - self.fft_bandpass = gr.fir_filter_ccc (decimation, - self.fft_input_taps) - else: - self.fft_input_rate = input_rate - - # Set up FFT display - if self.waterfall == False: - self.scope = ra_fftsink.ra_fft_sink_c (panel, - fft_size=int(self.fft_size), sample_rate=self.fft_input_rate, - fft_rate=int(self.fft_rate), title="Spectral", - ofunc=self.fft_outfunc, xydfunc=self.xydfunc) - else: - self.scope = ra_waterfallsink.waterfall_sink_c (panel, - fft_size=int(self.fft_size), sample_rate=self.fft_input_rate, - fft_rate=int(self.fft_rate), title="Spectral", ofunc=self.fft_outfunc, size=(1100, 600), xydfunc=self.xydfunc, ref_level=0, span=10) - - # Set up ephemeris data - self.locality = ephem.Observer() - self.locality.long = str(options.longitude) - self.locality.lat = str(options.latitude) - - # We make notes about Sunset/Sunrise in Continuum log files - self.sun = ephem.Sun() - self.sunstate = "??" - - # Set up stripchart display - tit = "Continuum" - if (self.dual_mode != False): - tit = "H+V Continuum" - if (self.interferometer != False): - tit = "East x West Correlation" - self.stripsize = int(options.stripsize) - if self.chartneeded == True: - self.chart = ra_stripchartsink.stripchart_sink_f (panel, - stripsize=self.stripsize, - title=tit, - xlabel="LMST Offset (Seconds)", - scaling=1.0, ylabel=options.ylabel, - divbase=options.divbase) - - # Set center frequency - self.centerfreq = options.freq - - # Set observing frequency (might be different from actual programmed - # RF frequency) - if options.observing == 0.0: - self.observing = options.freq - else: - self.observing = options.observing - - # Remember our input bandwidth - self.bw = input_rate - - # - # - # The strip chart is fed at a constant 1Hz rate - # - - # - # Call constructors for receive chains - # - - if (self.dual_mode == True): - self.setup_dual (self.setimode) - - if (self.interferometer == True): - self.setup_interferometer(self.setimode) - - if (self.normal_mode == True): - self.setup_normal(self.setimode) - - if (self.setimode == True): - self.setup_seti() - - self._build_gui(vbox) - - # Make GUI agree with command-line - self.integ = options.integ - if self.setimode == False: - self.myform['integration'].set_value(int(options.integ)) - self.myform['offset'].set_value(self.calib_offset) - self.myform['dcgain'].set_value(self.calib_coeff) - self.myform['average'].set_value(int(options.avg)) - - - if self.setimode == False: - # Make integrator agree with command line - self.set_integration(int(options.integ)) - - self.avg_alpha = options.avg - - # 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) - - if self.setimode == False: - # Set division size - self.chart.set_y_per_div(options.division) - # Set reference(MAX) level - self.chart.set_ref_level(options.reflevel) - - # set initial values - - if options.gain is None: - # if no gain was specified, use the mid-point in dB - g = self.subdev[0].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[0].freq_range() - options.freq = float(r[0]+r[1])/2 - - # Set the initial gain control - self.set_gain(options.gain) - - if not(self.set_freq(options.freq)): - self._set_status_msg("Failed to set initial frequency") - - # Set declination - self.set_decln (self.decln) - - - # RF hardware information - self.myform['decim'].set_value(self.u.decim_rate()) - self.myform['USB BW'].set_value(self.u.adc_freq() / self.u.decim_rate()) - if (self.dual_mode == True): - self.myform['dbname'].set_value(self.subdev[0].name()+'/'+self.subdev[1].name()) - else: - self.myform['dbname'].set_value(self.subdev[0].name()) - - # Set analog baseband filtering, if DBS_RX - if self.cardtype == usrp_dbid.DBS_RX: - lbw = (self.u.adc_freq() / self.u.decim_rate()) / 2 - if lbw < 1.0e6: - lbw = 1.0e6 - self.subdev[0].set_bw(lbw) - self.subdev[1].set_bw(lbw) - - # Start the timer for the LMST display and datalogging - self.lmst_timer.Start(1000) - if (self.switch_mode == True): - self.other_timer.Start(330) - - - def _set_status_msg(self, msg): - self.frame.GetStatusBar().SetStatusText(msg, 0) - - def _build_gui(self, vbox): - - def _form_set_freq(kv): - # Adjust current SETI frequency, and limits - self.setifreq_lower = kv['freq'] - (self.seti_freq_range/2) - self.setifreq_current = kv['freq'] - self.setifreq_upper = kv['freq'] + (self.seti_freq_range/2) - - # Reset SETI analysis timer - self.seti_then = time.time() - # Zero-out hits array when changing frequency - self.hits_array[:,:] = 0.0 - self.hit_intensities[:,:] = -60.0 - - return self.set_freq(kv['freq']) - - def _form_set_decln(kv): - return self.set_decln(kv['decln']) - - # Position the FFT display - vbox.Add(self.scope.win, 15, wx.EXPAND) - - if self.setimode == False: - # Position the Total-power stripchart - vbox.Add(self.chart.win, 15, wx.EXPAND) - - # add control area at the bottom - self.myform = myform = form.form() - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add((7,0), 0, wx.EXPAND) - vbox1 = wx.BoxSizer(wx.VERTICAL) - myform['freq'] = form.float_field( - parent=self.panel, sizer=vbox1, label="Center freq", weight=1, - callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg)) - - vbox1.Add((4,0), 0, 0) - - myform['lmst_high'] = form.static_text_field( - parent=self.panel, sizer=vbox1, label="Current LMST", weight=1) - vbox1.Add((4,0), 0, 0) - - if self.setimode == False: - myform['spec_data'] = form.static_text_field( - parent=self.panel, sizer=vbox1, label="Spectral Cursor", weight=1) - vbox1.Add((4,0), 0, 0) - - vbox2 = wx.BoxSizer(wx.VERTICAL) - if self.setimode == False: - vbox3 = wx.BoxSizer(wx.VERTICAL) - g = self.subdev[0].gain_range() - myform['gain'] = form.slider_field(parent=self.panel, sizer=vbox2, label="RF Gain", - weight=1, - min=int(g[0]), max=int(g[1]), - callback=self.set_gain) - - vbox2.Add((4,0), 0, 0) - if self.setimode == True: - max_savg = 100 - else: - max_savg = 3000 - myform['average'] = form.slider_field(parent=self.panel, sizer=vbox2, - label="Spectral Averaging (FFT frames)", weight=1, min=1, max=max_savg, callback=self.set_averaging) - - # Set up scan control button when in SETI mode - if (self.setimode == True): - # SETI scanning control - buttonbox = wx.BoxSizer(wx.HORIZONTAL) - self.scan_control = form.button_with_callback(self.panel, - label="Scan: On ", - callback=self.toggle_scanning) - - buttonbox.Add(self.scan_control, 0, wx.CENTER) - vbox2.Add(buttonbox, 0, wx.CENTER) - - vbox2.Add((4,0), 0, 0) - - if self.setimode == False: - myform['integration'] = form.slider_field(parent=self.panel, sizer=vbox2, - label="Continuum Integration Time (sec)", weight=1, min=1, max=180, callback=self.set_integration) - - vbox2.Add((4,0), 0, 0) - - myform['decln'] = form.float_field( - parent=self.panel, sizer=vbox2, label="Current Declination", weight=1, - callback=myform.check_input_and_call(_form_set_decln)) - vbox2.Add((4,0), 0, 0) - - if self.setimode == False: - myform['offset'] = form.slider_field(parent=self.panel, sizer=vbox3, - label="Post-Detector Offset", weight=1, min=-750, max=750, - callback=self.set_pd_offset) - vbox3.Add((2,0), 0, 0) - myform['dcgain'] = form.slider_field(parent=self.panel, sizer=vbox3, - label="Post-Detector Gain", weight=1, min=1, max=100, - callback=self.set_pd_gain) - vbox3.Add((2,0), 0, 0) - hbox.Add(vbox1, 0, 0) - hbox.Add(vbox2, wx.ALIGN_RIGHT, 0) - - if self.setimode == False: - hbox.Add(vbox3, wx.ALIGN_RIGHT, 0) - - vbox.Add(hbox, 0, wx.EXPAND) - - self._build_subpanel(vbox) - - self.lmst_timer = wx.PyTimer(self.lmst_timeout) - self.other_timer = wx.PyTimer(self.other_timeout) - - - def _build_subpanel(self, vbox_arg): - # build a secondary information panel (sometimes hidden) - - # FIXME figure out how to have this be a subpanel that is always - # created, but has its visibility controlled by foo.Show(True/False) - - if not(self.show_debug_info): - return - - panel = self.panel - vbox = vbox_arg - myform = self.myform - - #panel = wx.Panel(self.panel, -1) - #vbox = wx.BoxSizer(wx.VERTICAL) - - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add((5,0), 0) - myform['decim'] = form.static_float_field( - parent=panel, sizer=hbox, label="Decim") - - hbox.Add((5,0), 1) - myform['USB BW'] = form.static_float_field( - parent=panel, sizer=hbox, label="USB BW") - - hbox.Add((5,0), 1) - myform['dbname'] = form.static_text_field( - parent=panel, sizer=hbox) - - hbox.Add((5,0), 1) - myform['baseband'] = form.static_float_field( - parent=panel, sizer=hbox, label="Analog BB") - - hbox.Add((5,0), 1) - myform['ddc'] = form.static_float_field( - parent=panel, sizer=hbox, label="DDC") - - hbox.Add((5,0), 0) - vbox.Add(hbox, 0, wx.EXPAND) - - - - def set_freq(self, target_freq): - """ - Set the center frequency we're interested in. - - @param target_freq: frequency in Hz - - """ - # - # - r = usrp.tune(self.u, self.subdev[0].which(), self.subdev[0], target_freq) - r = usrp.tune(self.u, self.subdev[1].which(), self.subdev[1], target_freq) - if r: - self.myform['freq'].set_value(target_freq) # update displayed value - # - # Make sure calibrator knows our target freq - # - - # Remember centerfreq---used for doppler calcs - delta = self.centerfreq - target_freq - self.centerfreq = target_freq - self.observing -= delta - self.scope.set_baseband_freq (self.observing) - self.myform['baseband'].set_value(r.baseband_freq) - self.myform['ddc'].set_value(r.dxc_freq) - - if (self.use_notches): - self.compute_notch_taps(self.notches) - if self.dual_mode == False and self.interferometer == False: - self.notch_filt.set_taps(self.notch_taps) - else: - self.notch_filt1.set_taps(self.notch_taps) - self.notch_filt2.set_taps(self.notch_taps) - - return True - - return False - - def set_decln(self, dec): - self.decln = dec - self.myform['decln'].set_value(dec) # update displayed value - - def set_gain(self, gain): - self.myform['gain'].set_value(gain) # update displayed value - self.subdev[0].set_gain(gain) - self.subdev[1].set_gain(gain) - self.gain = gain - - def set_averaging(self, avval): - self.myform['average'].set_value(avval) - self.scope.set_avg_alpha(1.0/(avval)) - self.scope.set_average(True) - self.avg_alpha = avval - - def set_integration(self, integval): - if self.setimode == False: - self.integrator.set_taps(1.0/((integval)*(self.bw/2))) - self.myform['integration'].set_value(integval) - self.integ = integval - - # - # Timeout function - # Used to update LMST display, as well as current - # continuum value - # - # We also write external data-logging files here - # - def lmst_timeout(self): - self.locality.date = ephem.now() - if self.setimode == False: - x = self.probe.level() - sidtime = self.locality.sidereal_time() - # LMST - s = str(ephem.hours(sidtime)) + " " + self.sunstate - # Continuum detector value - if self.setimode == False: - sx = "%7.4f" % x - s = s + "\nDet: " + str(sx) - else: - sx = "%2d" % self.hitcounter - s1 = "%2d" % self.s1hitcounter - s2 = "%2d" % self.s2hitcounter - sa = "%4.2f" % self.avgdelta - sy = "%3.1f-%3.1f" % (self.CHIRP_LOWER, self.CHIRP_UPPER) - s = s + "\nHits: " + str(sx) + "\nS1:" + str(s1) + " S2:" + str(s2) - s = s + "\nAv D: " + str(sa) + "\nCh lim: " + str(sy) - - self.myform['lmst_high'].set_value(s) - - # - # Write data out to recording files - # - if self.setimode == False: - self.write_continuum_data(x,sidtime) - self.write_spectral_data(self.fft_outbuf,sidtime) - - else: - self.seti_analysis(self.fft_outbuf,sidtime) - now = time.time() - if ((self.scanning == True) and ((now - self.seti_then) > self.setifreq_timer)): - self.seti_then = now - self.setifreq_current = self.setifreq_current + self.fft_input_rate - if (self.setifreq_current > self.setifreq_upper): - self.setifreq_current = self.setifreq_lower - self.set_freq(self.setifreq_current) - # Make sure we zero-out the hits array when changing - # frequency. - self.hits_array[:,:] = 0.0 - self.hit_intensities[:,:] = 0.0 - - def other_timeout(self): - if (self.switch_state == 0): - self.switch_state = 1 - - elif (self.switch_state == 1): - self.switch_state = 0 - - if (self.switch_state == 0): - self.mute.set_n(1) - self.cmute.set_n(int(1.0e9)) - - elif (self.switch_state == 1): - self.mute.set_n(int(1.0e9)) - self.cmute.set_n(1) - - if (self.ref_fifo != "@@@@"): - self.ref_fifo_file.write(str(self.switch_state)+"\n") - self.ref_fifo_file.flush() - - self.avg_reference_value = self.cprobe.level() - - # - # Set reference value - # - self.reference_level.set_k(-1.0 * (self.avg_reference_value/self.reference_divisor)) - - def fft_outfunc(self,data,l): - self.fft_outbuf=data - - def write_continuum_data(self,data,sidtime): - - # Create localtime structure for producing filename - foo = time.localtime() - pfx = self.prefix - filenamestr = "%s/%04d%02d%02d%02d" % (pfx, foo.tm_year, - foo.tm_mon, foo.tm_mday, foo.tm_hour) - - # Open the data file, appending - continuum_file = open (filenamestr+".tpdat","a") - - flt = "%6.3f" % data - inter = self.decln - integ = self.integ - fc = self.observing - fc = fc / 1000000 - bw = self.bw - bw = bw / 1000000 - ga = self.gain - - now = time.time() - - # - # If time to write full header info (saves storage this way) - # - if (now - self.continuum_then > 20): - self.sun.compute(self.locality) - enow = ephem.now() - sunset = self.locality.next_setting(self.sun) - sunrise = self.locality.next_rising(self.sun) - sun_insky = "Down" - self.sunstate = "Dn" - if ((sunrise < enow) and (enow < sunset)): - sun_insky = "Up" - self.sunstate = "Up" - self.continuum_then = now - - continuum_file.write(str(ephem.hours(sidtime))+" "+flt+" Dn="+str(inter)+",") - continuum_file.write("Ti="+str(integ)+",Fc="+str(fc)+",Bw="+str(bw)) - continuum_file.write(",Ga="+str(ga)+",Sun="+str(sun_insky)+"\n") - else: - continuum_file.write(str(ephem.hours(sidtime))+" "+flt+"\n") - - continuum_file.close() - return(data) - - def write_spectral_data(self,data,sidtime): - - now = time.time() - delta = 10 - - # If time to write out spectral data - # We don't write this out every time, in order to - # save disk space. Since the spectral data are - # typically heavily averaged, writing this data - # "once in a while" is OK. - # - if (now - self.spectral_then >= delta): - self.spectral_then = now - - # Get localtime structure to make filename from - foo = time.localtime() - - pfx = self.prefix - filenamestr = "%s/%04d%02d%02d%02d" % (pfx, foo.tm_year, - foo.tm_mon, foo.tm_mday, foo.tm_hour) - - # Open the file - spectral_file = open (filenamestr+".sdat","a") - - # Setup data fields to be written - r = data - inter = self.decln - fc = self.observing - fc = fc / 1000000 - bw = self.bw - bw = bw / 1000000 - av = self.avg_alpha - - # Write those fields - spectral_file.write("data:"+str(ephem.hours(sidtime))+" Dn="+str(inter)+",Fc="+str(fc)+",Bw="+str(bw)+",Av="+str(av)) - spectral_file.write (" [ ") - for r in data: - spectral_file.write(" "+str(r)) - - spectral_file.write(" ]\n") - spectral_file.close() - return(data) - - return(data) - - def seti_analysis(self,fftbuf,sidtime): - l = len(fftbuf) - x = 0 - hits = [] - hit_intensities = [] - if self.seticounter < self.setitimer: - self.seticounter = self.seticounter + 1 - return - else: - self.seticounter = 0 - - # Run through FFT output buffer, computing standard deviation (Sigma) - avg = 0 - # First compute average - for i in range(0,l): - avg = avg + fftbuf[i] - avg = avg / l - - sigma = 0.0 - # Then compute standard deviation (Sigma) - for i in range(0,l): - d = fftbuf[i] - avg - sigma = sigma + (d*d) - - sigma = Numeric.sqrt(sigma/l) - - # - # Snarfle through the FFT output buffer again, looking for - # outlying data points - - start_f = self.observing - (self.fft_input_rate/2) - current_f = start_f - l = len(fftbuf) - f_incr = self.fft_input_rate / l - hit = -1 - - # -nyquist to DC - for i in range(l/2,l): - # - # If current FFT buffer has an item that exceeds the specified - # sigma - # - if ((fftbuf[i] - avg) > (self.setik * sigma)): - hits.append(current_f) - hit_intensities.append(fftbuf[i]) - current_f = current_f + f_incr - - # DC to nyquist - for i in range(0,l/2): - # - # If current FFT buffer has an item that exceeds the specified - # sigma - # - if ((fftbuf[i] - avg) > (self.setik * sigma)): - hits.append(current_f) - hit_intensities.append(fftbuf[i]) - current_f = current_f + f_incr - - # No hits - if (len(hits) <= 0): - return - - - # - # OK, so we have some hits in the FFT buffer - # They'll have a rather substantial gauntlet to run before - # being declared a real "hit" - # - - # Update stats - self.s1hitcounter = self.s1hitcounter + len(hits) - - # Weed out buffers with an excessive number of - # signals above Sigma - if (len(hits) > self.nhits): - return - - - # Weed out FFT buffers with apparent multiple narrowband signals - # separated significantly in frequency. This means that a - # single signal spanning multiple bins is OK, but a buffer that - # has multiple, apparently-separate, signals isn't OK. - # - last = hits[0] - ns2 = 1 - for i in range(1,len(hits)): - if ((hits[i] - last) > (f_incr*3.0)): - return - last = hits[i] - ns2 = ns2 + 1 - - self.s2hitcounter = self.s2hitcounter + ns2 - - # - # Run through all available hit buffers, computing difference between - # frequencies found there, if they're all within the chirp limits - # declare a good hit - # - good_hit = False - f_ds = Numeric.zeros(self.nhitlines, Numeric.Float64) - avg_delta = 0 - k = 0 - for i in range(0,min(len(hits),len(self.hits_array[:,0]))): - f_ds[0] = abs(self.hits_array[i,0] - hits[i]) - for j in range(1,len(f_ds)): - f_ds[j] = abs(self.hits_array[i,j] - self.hits_array[i,0]) - avg_delta = avg_delta + f_ds[j] - k = k + 1 - - if (self.seti_isahit (f_ds)): - good_hit = True - self.hitcounter = self.hitcounter + 1 - break - - if (avg_delta/k < (self.seti_fft_bandwidth/2)): - self.avgdelta = avg_delta / k - - # Save 'n shuffle hits - # Old hit buffers percolate through the hit buffers - # (there are self.nhitlines of these buffers) - # and then drop off the end - # A consequence is that while the nhitlines buffers are filling, - # you can get some absurd values for self.avgdelta, because some - # of the buffers are full of zeros - for i in range(self.nhitlines,1): - self.hits_array[:,i] = self.hits_array[:,i-1] - self.hit_intensities[:,i] = self.hit_intensities[:,i-1] - - for i in range(0,len(hits)): - self.hits_array[i,0] = hits[i] - self.hit_intensities[i,0] = hit_intensities[i] - - # Finally, write the hits/intensities buffer - if (good_hit): - self.write_hits(sidtime) - - return - - def seti_isahit(self,fdiffs): - truecount = 0 - - for i in range(0,len(fdiffs)): - if (fdiffs[i] >= self.CHIRP_LOWER and fdiffs[i] <= self.CHIRP_UPPER): - truecount = truecount + 1 - - if truecount == len(fdiffs): - return (True) - else: - return (False) - - def write_hits(self,sidtime): - # Create localtime structure for producing filename - foo = time.localtime() - pfx = self.prefix - filenamestr = "%s/%04d%02d%02d%02d" % (pfx, foo.tm_year, - foo.tm_mon, foo.tm_mday, foo.tm_hour) - - # Open the data file, appending - hits_file = open (filenamestr+".seti","a") - - # Write sidtime first - hits_file.write(str(ephem.hours(sidtime))+" "+str(self.decln)+" ") - - # - # Then write the hits/hit intensities buffers with enough - # "syntax" to allow parsing by external (not yet written!) - # "stuff". - # - for i in range(0,self.nhitlines): - hits_file.write(" ") - for j in range(0,self.nhits): - hits_file.write(str(self.hits_array[j,i])+":") - hits_file.write(str(self.hit_intensities[j,i])+",") - hits_file.write("\n") - hits_file.close() - return - - def xydfunc(self,func,xyv): - if self.setimode == True: - return - magn = int(Numeric.log10(self.observing)) - if (magn == 6 or magn == 7 or magn == 8): - magn = 6 - dfreq = xyv[0] * pow(10.0,magn) - if func == 0: - ratio = self.observing / dfreq - vs = 1.0 - ratio - vs *= 299792.0 - if magn >= 9: - xhz = "Ghz" - elif magn >= 6: - xhz = "Mhz" - elif magn <= 5: - xhz = "Khz" - s = "%.6f%s\n%.3fdB" % (xyv[0], xhz, xyv[1]) - s2 = "\n%.3fkm/s" % vs - self.myform['spec_data'].set_value(s+s2) - else: - tmpnotches = Numeric.zeros(self.NOTCH_TAPS,Numeric.Float64) - delfreq = -1 - if self.use_notches == True: - for i in range(0,len(self.notches)): - if self.notches[i] != 0 and abs(self.notches[i] - dfreq) < ((self.bw/self.NOTCH_TAPS)/2.0): - delfreq = i - break - j = 0 - for i in range(0,len(self.notches)): - if (i != delfreq): - tmpnotches[j] = self.notches[i] - j = j + 1 - if (delfreq == -1): - for i in range(0,len(tmpnotches)): - if (int(tmpnotches[i]) == 0): - tmpnotches[i] = dfreq - break - self.notches = tmpnotches - self.compute_notch_taps(self.notches) - if self.dual_mode == False and self.interferometer == False: - self.notch_filt.set_taps(self.notch_taps) - else: - self.notch_filt1.set_taps(self.notch_taps) - self.notch_filt2.set_taps(self.notch_taps) - - def xydfunc_waterfall(self,pos): - lower = self.observing - (self.seti_fft_bandwidth / 2) - upper = self.observing + (self.seti_fft_bandwidth / 2) - binwidth = self.seti_fft_bandwidth / 1024 - s = "%.6fMHz" % ((lower + (pos.x*binwidth)) / 1.0e6) - self.myform['spec_data'].set_value(s) - - def toggle_cal(self): - if (self.calstate == True): - self.calstate = False - self.u.write_io(0,0,(1<<15)) - self.calibrator.SetLabel("Calibration Source: Off") - else: - self.calstate = True - self.u.write_io(0,(1<<15),(1<<15)) - self.calibrator.SetLabel("Calibration Source: On") - - def toggle_annotation(self): - if (self.annotate_state == True): - self.annotate_state = False - self.annotation.SetLabel("Annotation: Off") - else: - self.annotate_state = True - self.annotation.SetLabel("Annotation: On") - # - # Turn scanning on/off - # Called-back by "Recording" button - # - def toggle_scanning(self): - # Current scanning? Flip state - if (self.scanning == True): - self.scanning = False - self.scan_control.SetLabel("Scan: Off") - # Not scanning - else: - self.scanning = True - self.scan_control.SetLabel("Scan: On ") - - def set_pd_offset(self,offs): - self.myform['offset'].set_value(offs) - self.calib_offset=offs - x = self.calib_coeff / 100.0 - self.cal_offs.set_k(offs*(x*8000)) - - def set_pd_gain(self,gain): - self.myform['dcgain'].set_value(gain) - self.cal_mult.set_k(gain*0.01) - self.calib_coeff = gain - x = gain/100.0 - self.cal_offs.set_k(self.calib_offset*(x*8000)) - - def compute_notch_taps(self,notchlist): - tmptaps = Numeric.zeros(self.NOTCH_TAPS,Numeric.Complex64) - binwidth = self.bw / self.NOTCH_TAPS - - for i in range(0,self.NOTCH_TAPS): - tmptaps[i] = complex(1.0,0.0) - - for i in notchlist: - diff = i - self.observing - if int(i) == 0: - break - if ((i < (self.observing - self.bw/2)) or (i > (self.observing + self.bw/2))): - continue - if (diff > 0): - idx = diff / binwidth - idx = round(idx) - idx = int(idx) - if (idx < 0 or idx > (self.NOTCH_TAPS/2)): - break - tmptaps[idx] = complex(0.0, 0.0) - - if (diff < 0): - idx = -diff / binwidth - idx = round(idx) - idx = (self.NOTCH_TAPS/2) - idx - idx = int(idx+(self.NOTCH_TAPS/2)) - if (idx < 0 or idx >= (self.NOTCH_TAPS)): - break - tmptaps[idx] = complex(0.0, 0.0) - - self.notch_taps = numpy.fft.ifft(tmptaps) - - # - # Setup common pieces of radiometer mode - # - def setup_radiometer_common(self,n): - # The IIR integration filter for post-detection - self.integrator = gr.single_pole_iir_filter_ff(1.0) - self.integrator.set_taps (1.0/self.bw) - - if (self.use_notches == True): - self.compute_notch_taps(self.notches) - if (n == 2): - self.notch_filt1 = gr.fft_filter_ccc(1, self.notch_taps) - self.notch_filt2 = gr.fft_filter_ccc(1, self.notch_taps) - else: - self.notch_filt = gr.fft_filter_ccc(1, self.notch_taps) - - - # Signal probe - self.probe = gr.probe_signal_f() - - # - # Continuum calibration stuff - # - x = self.calib_coeff/100.0 - self.cal_mult = gr.multiply_const_ff(self.calib_coeff/100.0) - self.cal_offs = gr.add_const_ff(self.calib_offset*(x*8000)) - - # - # Mega decimator after IIR filter - # - if (self.switch_mode == False): - self.keepn = gr.keep_one_in_n(gr.sizeof_float, self.bw) - else: - self.keepn = gr.keep_one_in_n(gr.sizeof_float, int(self.bw/2)) - - # - # For the Dicke-switching scheme - # - #self.switch = gr.multiply_const_ff(1.0) - - # - if (self.switch_mode == True): - self.vector = gr.vector_sink_f() - self.swkeep = gr.keep_one_in_n(gr.sizeof_float, int(self.bw/3)) - self.mute = gr.keep_one_in_n(gr.sizeof_float, 1) - self.cmute = gr.keep_one_in_n(gr.sizeof_float, int(1.0e9)) - self.cintegrator = gr.single_pole_iir_filter_ff(1.0/(self.bw/2)) - self.cprobe = gr.probe_signal_f() - else: - self.mute = gr.multiply_const_ff(1.0) - - - self.avg_reference_value = 0.0 - self.reference_level = gr.add_const_ff(0.0) - - # - # Setup ordinary single-channel radiometer mode - # - 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 - - # - # Setup dual-channel (two antenna, usual orthogonal polarity probes in the same waveguide) - # - def setup_dual(self, setimode): - - self.setup_radiometer_common(2) - - self.di = gr.deinterleave(gr.sizeof_gr_complex) - self.addchans = gr.add_cc () - self.detector = gr.add_ff () - self.h_power = gr.complex_to_mag_squared() - self.v_power = gr.complex_to_mag_squared() - self.connect (self.u, self.di) - - if (self.use_notches == True): - self.connect((self.di, 0), self.notch_filt1, (self.addchans, 0)) - self.connect((self.di, 1), self.notch_filt2, (self.addchans, 1)) - else: - # - # For spectral, adding the two channels works, assuming no gross - # phase or amplitude error - self.connect ((self.di, 0), (self.addchans, 0)) - self.connect ((self.di, 1), (self.addchans, 1)) - - # - # Connect heads of spectral and total-power chains - # - if (self.use_notches == False): - self.head = self.di - else: - self.head = (self.notch_filt1, self.notch_filt2) - - self.shead = self.addchans - - if (setimode == False): - # - # For dual-polarization mode, we compute the sum of the - # powers on each channel, after they've been detected - # - self.detector = gr.add_ff() - - # - # In dual-polarization mode, we compute things a little differently - # In effect, we have two radiometer chains, terminating in an adder - # - if self.use_notches == True: - self.connect(self.notch_filt1, self.h_power) - self.connect(self.notch_filt2, self.v_power) - else: - self.connect((self.head, 0), self.h_power) - self.connect((self.head, 1), self.v_power) - self.connect(self.h_power, (self.detector, 0)) - self.connect(self.v_power, (self.detector, 1)) - self.connect(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) - self.connect(self.shead, self.scope) - - # - # 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 - - # - # Setup correlating interferometer mode - # - def setup_interferometer(self, setimode): - self.setup_radiometer_common(2) - - self.di = gr.deinterleave(gr.sizeof_gr_complex) - self.connect (self.u, self.di) - self.corr = gr.multiply_cc() - self.c2f = gr.complex_to_float() - - self.shead = (self.di, 0) - - # Channel 0 to multiply port 0 - # Channel 1 to multiply port 1 - if (self.use_notches == False): - self.connect((self.di, 0), (self.corr, 0)) - self.connect((self.di, 1), (self.corr, 1)) - else: - self.connect((self.di, 0), self.notch_filt1, (self.corr, 0)) - self.connect((self.di, 1), self.notch_filt2, (self.corr, 0)) - - # - # Multiplier (correlator) to complex-to-float, followed by integrator, etc - # - self.connect(self.corr, self.c2f, self.integrator, self.keepn, self.cal_mult, self.cal_offs, self.chart) - - # - # FFT scope gets only 1 channel - # FIX THIS, by cross-correlating the *outputs* of two different FFTs, then display - # Funky! - # - self.connect(self.shead, self.scope) - - # - # Output of correlator/integrator chain to probe - # - self.connect(self.cal_offs, self.probe) - - return - - # - # Setup SETI mode - # - def setup_seti(self): - self.connect (self.shead, self.fft_bandpass, self.scope) - return - - def setup_usrp(self): - - if (self.usrp2 == False): - if (self.dual_mode == False and self.interferometer == False): - if (self.decim > 4): - self.u = usrp.source_c(decim_rate=self.decim,fusb_block_size=8192) - else: - self.u = usrp.source_c(decim_rate=self.decim,fusb_block_size=8192, fpga_filename="std_4rx_0tx.rbf") - self.u.set_mux(usrp.determine_rx_mux_value(self.u, self.rx_subdev_spec)) - # determine the daughterboard subdevice we're using - self.subdev[0] = usrp.selected_subdev(self.u, self.rx_subdev_spec) - self.subdev[1] = self.subdev[0] - self.cardtype = self.subdev[0].dbid() - else: - self.u=usrp.source_c(decim_rate=self.decim, nchan=2,fusb_block_size=8192) - self.subdev[0] = usrp.selected_subdev(self.u, (0, 0)) - self.subdev[1] = usrp.selected_subdev(self.u, (1, 0)) - self.cardtype = self.subdev[0].dbid() - self.u.set_mux(0x32103210) - c1 = self.subdev[0].name() - c2 = self.subdev[1].name() - if (c1 != c2): - print "Must have identical cardtypes for --dual_mode or --interferometer" - sys.exit(1) - # - # Set 8-bit mode - # - - width = 8 - shift = 8 - format = self.u.make_format(width, shift) - r = self.u.set_format(format) - else: - if (self.dual_mode == True or self.interferometer == True): - print "Cannot use dual_mode or interferometer with single USRP2" - sys.exit(1) - self.u = usrp2.source_32fc(self.interface, self.mac_addr) - self.u.set_decim (self.decim) - self.cardtype = self.u.daughterboard_id() - -def main (): - app = stdgui2.stdapp(app_flow_graph, "RADIO ASTRONOMY SPECTRAL/CONTINUUM RECEIVER: $Revision$", nstatus=1) - app.MainLoop() - -if __name__ == '__main__': - main () diff --git a/gr-uhd/examples/Makefile.am b/gr-uhd/examples/Makefile.am index b10b48928..a5dc177c4 100644 --- a/gr-uhd/examples/Makefile.am +++ b/gr-uhd/examples/Makefile.am @@ -21,7 +21,7 @@ include $(top_srcdir)/Makefile.common -SUBDIRS = multi-antenna +SUBDIRS = ourdatadir = $(exampledir)/uhd diff --git a/gr-uhd/examples/fm_tx4.py b/gr-uhd/examples/fm_tx4.py index 9b39752c1..7b04ebd73 100755 --- a/gr-uhd/examples/fm_tx4.py +++ b/gr-uhd/examples/fm_tx4.py @@ -83,9 +83,8 @@ class fm_tx_block(stdgui2.std_top_block): stdgui2.std_top_block.__init__ (self, frame, panel, vbox, argv) parser = OptionParser (option_class=eng_option) - parser.add_option("-a", "--address", type="string", - default="addr=192.168.10.2", - help="Address of UHD device, [default=%default]") + parser.add_option("-a", "--args", type="string", default="", + help="UHD device address args [default=%default]") 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=400e3, @@ -116,7 +115,7 @@ class fm_tx_block(stdgui2.std_top_block): # ---------------------------------------------------------------- # Set up constants and parameters - self.u = uhd.usrp_sink(device_addr=options.address, + self.u = uhd.usrp_sink(device_addr=options.args, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=1) diff --git a/gr-uhd/examples/fm_tx_2_daughterboards.py b/gr-uhd/examples/fm_tx_2_daughterboards.py index 36d237616..25325bd19 100755 --- a/gr-uhd/examples/fm_tx_2_daughterboards.py +++ b/gr-uhd/examples/fm_tx_2_daughterboards.py @@ -88,9 +88,8 @@ class my_top_block(gr.top_block): usage="%prog: [options] tx-freq0 tx-freq1" parser = OptionParser (option_class=eng_option, usage=usage) - parser.add_option("-a", "--address", type="string", - default="addr=192.168.10.2", - help="Address of UHD device, [default=%default]") + parser.add_option("-a", "--args", type="string", default="", + help="UHD device address args [default=%default]") 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=320e3, @@ -109,10 +108,10 @@ class my_top_block(gr.top_block): # ---------------------------------------------------------------- # Set up USRP to transmit on both daughterboards - d = uhd.device_find(uhd.device_addr(options.address)) + d = uhd.find_devices(uhd.device_addr(options.args)) uhd_type = d[0].get('type') - self.u = uhd.usrp_sink(device_addr=options.address, + self.u = uhd.usrp_sink(device_addr=options.args, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=2) diff --git a/gr-uhd/examples/max_power.py b/gr-uhd/examples/max_power.py index 44d3beeee..53e1b413c 100755 --- a/gr-uhd/examples/max_power.py +++ b/gr-uhd/examples/max_power.py @@ -39,14 +39,14 @@ n2s = eng_notation.num_to_str MAX_RATE = 1000e6 class build_block(gr.top_block): - def __init__(self, address, tx_enable, rx_enable): + def __init__(self, args, tx_enable, rx_enable): gr.top_block.__init__(self) - d = uhd.device_find(uhd.device_addr(address)) + d = uhd.find_devices(uhd.device_addr(args)) uhd_type = d[0].get('type') - print "\nFound '%s' at address '%s'" % \ - (uhd_type, address) + print "\nFound '%s' at args '%s'" % \ + (uhd_type, args) # Test the type of USRP; if it's a USRP (v1), it has # 2 channels; otherwise, it has 1 channel @@ -59,7 +59,7 @@ class build_block(gr.top_block): if tx_enable: print "\nTRANSMIT CHAIN" - self.u_tx = uhd.usrp_sink(device_addr=address, + self.u_tx = uhd.usrp_sink(device_addr=args, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=tx_nchan) self.u_tx.set_samp_rate(MAX_RATE) @@ -92,7 +92,7 @@ class build_block(gr.top_block): if rx_enable: print "\nRECEIVE CHAIN" - self.u_rx = uhd.usrp_source(device_addr=address, + self.u_rx = uhd.usrp_source(device_addr=args, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=rx_nchan) self.rx_dst0 = gr.null_sink (gr.sizeof_gr_complex) @@ -123,16 +123,15 @@ class build_block(gr.top_block): def main (): parser = OptionParser (option_class=eng_option) - parser.add_option("-a", "--address", type="string", - default="addr=192.168.10.2", - help="Address of UHD device, [default=%default]") + parser.add_option("-a", "--args", type="string", default="", + help="UHD device address args [default=%default]") parser.add_option("-t", action="store_true", dest="tx_enable", default=False, help="enable Tx path") parser.add_option("-r", action="store_true", dest="rx_enable", default=False, help="enable Rx path") (options, args) = parser.parse_args () - tb = build_block (options.address, options.tx_enable, options.rx_enable) + tb = build_block (options.args, options.tx_enable, options.rx_enable) tb.start () raw_input ('Press Enter to quit: ') diff --git a/gr-uhd/examples/multi-antenna/.gitignore b/gr-uhd/examples/multi-antenna/.gitignore deleted file mode 100644 index ff40c06f3..000000000 --- a/gr-uhd/examples/multi-antenna/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -/Makefile -/Makefile.in -/.la -/.lo -/.deps -/.libs -/*.la -/*.lo -/*.pyc -/*.pyo -/*.dat diff --git a/gr-uhd/examples/multi-antenna/Makefile.am b/gr-uhd/examples/multi-antenna/Makefile.am deleted file mode 100644 index 0cb944589..000000000 --- a/gr-uhd/examples/multi-antenna/Makefile.am +++ /dev/null @@ -1,29 +0,0 @@ -# -# Copyright 2006,2009 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. -# - -include $(top_srcdir)/Makefile.common - -ourdatadir = $(exampledir)/multi-antenna - -dist_ourdata_SCRIPTS = \ - multi_fft.py \ - multi_file.py \ - multi_scope.py diff --git a/gr-uhd/examples/multi-antenna/multi_fft.py b/gr-uhd/examples/multi-antenna/multi_fft.py deleted file mode 100755 index d4c878c84..000000000 --- a/gr-uhd/examples/multi-antenna/multi_fft.py +++ /dev/null @@ -1,152 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2011 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. -# - -from gnuradio import gr, eng_notation -from gnuradio import uhd -from gnuradio.eng_option import eng_option -from gnuradio import eng_notation -from gnuradio import optfir -from optparse import OptionParser -from gnuradio.wxgui import stdgui2, fftsink2, waterfallsink2 -from gnuradio.wxgui import scopesink2, form, slider -import wx -import time -import os.path -import sys - -# required FPGA that can do 4 rx channels. - -class my_graph(stdgui2.std_top_block): - - 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("-a", "--address", type="string", - default="addr=192.168.10.2", - help="Address of UHD device, [default=%default]") - 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 (bandwidth) [default=%default]") - parser.add_option("-f", "--freq", type="eng_float", default=None, - help="set frequency to FREQ", metavar="FREQ") - parser.add_option("-g", "--gain", type="eng_float", default=None, - help="set gain in dB (default is midpoint)") - parser.add_option("-F", "--filter", action="store_true", default=True, - help="Enable channel filter") - parser.add_option("-N", "--nchans", type="int", default=1, - help="set number of channels (default=%default)") - (options, args) = parser.parse_args() - - if len(args) != 0: - parser.print_help() - raise SystemExit - - self.nchans = options.nchans - - if options.filter: - sw_decim = 4 - else: - sw_decim = 1 - - self.u = uhd.usrp_source(device_addr=options.address, - io_type=uhd.io_type.COMPLEX_FLOAT32, - num_channels=self.nchans) - self.u.set_samp_rate(options.samp_rate) - input_rate = self.u.get_samp_rate() - - 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 - - if options.freq is None: - # if no freq was specified, use the mid-point - r = self.u.get_freq_range() - options.freq = float(r.start()+r.stop())/2 - - self.set_gain(options.gain) - self.set_freq(options.freq) - - #if self.u.nddcs() < nchan: - # sys.stderr.write('This code requires an FPGA build with %d DDCs. This FPGA has only %d.\n' % ( - # nchan, self.u.nddcs())) - # raise SystemExit - - #if (len (self.subdev) < 4 or - # self.u.db(0, 0).dbid() != usrp_dbid.BASIC_RX or - # self.u.db(0, 0).dbid() != usrp_dbid.BASIC_RX): - # sys.stderr.write('This code requires a Basic Rx board on Sides A & B\n') - # sys.exit(1) - - # deinterleave four channels from FPGA - di = gr.deinterleave(gr.sizeof_gr_complex) - - self.connect(self.u, di) - - # taps for channel filter - chan_filt_coeffs = optfir.low_pass (1, # gain - input_rate, # sampling rate - 80e3, # passband cutoff - 115e3, # stopband cutoff - 0.1, # passband ripple - 60) # stopband attenuation - #print len(chan_filt_coeffs) - - for i in range(self.nchans): - scope = fftsink2.fft_sink_c(panel, sample_rate=input_rate/sw_decim, - title="Input %d" % (i,), - ref_level=80, y_per_div=20) - vbox.Add(scope.win, 10, wx.EXPAND) - - if options.filter: - chan_filt = gr.fir_filter_ccf(sw_decim, chan_filt_coeffs) - self.connect((di, i), chan_filt, scope) - else: - self.connect((di, i), scope) - - def set_gain(self, gain): - for i in range(self.nchans): - self.u.set_gain(gain, i) - - - def set_freq(self, target_freq): - for i in range(self.nchans): - r = self.u.set_center_freq(target_freq, 0) - - if r: - return True - else: - print "set_freq: failed to set subdev[%d] freq to %f" % \ - (i, target_freq) - return False - -def main (): - app = stdgui2.stdapp(my_graph, "Multi Scope", nstatus=1) - app.MainLoop() - -if __name__ == '__main__': - main () diff --git a/gr-uhd/examples/multi-antenna/multi_file.py b/gr-uhd/examples/multi-antenna/multi_file.py deleted file mode 100755 index 87d9085e3..000000000 --- a/gr-uhd/examples/multi-antenna/multi_file.py +++ /dev/null @@ -1,134 +0,0 @@ -#!/usr/bin/env python - -from gnuradio import gr, gru, eng_notation -from gnuradio import usrp -from gnuradio.eng_option import eng_option -from gnuradio import eng_notation -from gnuradio import optfir -from optparse import OptionParser -from usrpm import usrp_dbid -import time -import os.path -import sys - -# required FPGA that can do 4 rx channels. - - -class my_graph(gr.top_block): - - def __init__(self): - gr.top_block.__init__(self) - - parser = OptionParser (option_class=eng_option) - #parser.add_option("-S", "--subdev", type="subdev", default=(0, None), - # help="select USRP Rx side A or B (default=A)") - parser.add_option("-d", "--decim", type="int", default=128, - help="set fgpa decimation rate to DECIM [default=%default]") - parser.add_option("-f", "--freq", type="eng_float", default=146.585e6, - help="set frequency to FREQ [default=%default])", metavar="FREQ") - parser.add_option("-g", "--gain", type="eng_float", default=20, - help="set gain in dB [default=%default]") - parser.add_option("-F", "--filter", action="store_true", default=True, - help="Enable channel filter") - parser.add_option("-o", "--output", type="string", default=None, - help="set output basename") - (options, args) = parser.parse_args() - - if len(args) != 0: - parser.print_help() - raise SystemExit - - if options.output is None: - parser.print_help() - sys.stderr.write("You must provide an output filename base with -o OUTPUT\n") - raise SystemExit - else: - basename = options.output - - nchan = 4 - nsecs = 4.0 - - if options.filter: - sw_decim = 4 - else: - sw_decim = 1 - - self.u = usrp.source_c(0, options.decim, fpga_filename="std_4rx_0tx.rbf") - if self.u.nddcs() < nchan: - sys.stderr.write('This code requires an FPGA build with %d DDCs. This FPGA has only %d.\n' % ( - nchan, self.u.nddcs())) - raise SystemExit - - if not self.u.set_nchannels(nchan): - sys.stderr.write('set_nchannels(%d) failed\n' % (nchan,)) - raise SystemExit - - input_rate = self.u.adc_freq() / self.u.decim_rate() - print "USB data rate = %s" % (eng_notation.num_to_str(input_rate),) - sink_data_rate = input_rate/sw_decim - print "Scope data rate = %s" % (eng_notation.num_to_str(sink_data_rate),) - - self.subdev = self.u.db(0) + self.u.db(1) - - if (len(self.subdev) < 4 or - self.u.db(0, 0).dbid() != usrp_dbid.BASIC_RX or - self.u.db(1, 0).dbid() != usrp_dbid.BASIC_RX): - sys.stderr.write('This code requires a Basic Rx board on Sides A & B\n') - sys.exit(1) - - self.u.set_mux(gru.hexint(0xf3f2f1f0)) - - # collect 1 second worth of data - limit = int(nsecs * input_rate * nchan) - print "limit = ", limit - head = gr.head(gr.sizeof_gr_complex, limit) - - # deinterleave four channels from FPGA - di = gr.deinterleave(gr.sizeof_gr_complex) - - self.connect(self.u, head, di) - - # taps for channel filter - chan_filt_coeffs = optfir.low_pass (1, # gain - input_rate, # sampling rate - 80e3, # passband cutoff - 115e3, # stopband cutoff - 0.1, # passband ripple - 60) # stopband attenuation - #print len(chan_filt_coeffs) - - for i in range(nchan): - - sink = gr.file_sink(gr.sizeof_gr_complex, - basename + ("-%s-%d.dat" % (eng_notation.num_to_str(sink_data_rate), i))) - if options.filter: - chan_filt = gr.fir_filter_ccf(sw_decim, chan_filt_coeffs) - self.connect((di, i), chan_filt, sink) - else: - self.connect((di, i), sink) - - - self.set_gain(options.gain) - self.set_freq(options.freq) - - def set_gain(self, gain): - for i in range(len(self.subdev)): - self.subdev[i].set_gain(gain) - - def set_freq(self, target_freq): - ok = True - for i in range(len(self.subdev)): - r = usrp.tune(self.u, i, self.subdev[i], target_freq) - if not r: - ok = False - print "set_freq: failed to set subdev[%d] freq to %f" % ( - i, target_freq) - - return ok - - -def main (): - my_graph().run() - -if __name__ == '__main__': - main () diff --git a/gr-uhd/examples/multi-antenna/multi_scope.py b/gr-uhd/examples/multi-antenna/multi_scope.py deleted file mode 100755 index d1e28ad18..000000000 --- a/gr-uhd/examples/multi-antenna/multi_scope.py +++ /dev/null @@ -1,139 +0,0 @@ -#!/usr/bin/env python - -from gnuradio import gr, gru, eng_notation -from gnuradio import usrp -from gnuradio.eng_option import eng_option -from gnuradio import eng_notation -from gnuradio import optfir -from optparse import OptionParser -from gnuradio.wxgui import stdgui2, fftsink2, waterfallsink2, scopesink2, form, slider -import wx -from usrpm import usrp_dbid -import time -import os.path -import sys - -# required FPGA that can do 4 rx channels. - - -class my_top_block(stdgui2.std_top_block): - - 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("-S", "--subdev", type="subdev", default=(0, None), - # help="select USRP Rx side A or B (default=A)") - parser.add_option("-d", "--decim", type="int", default=128, - help="set fgpa decimation rate to DECIM [default=%default]") - parser.add_option("-f", "--freq", type="eng_float", default=146.585e6, - help="set frequency to FREQ [default=%default])", metavar="FREQ") - parser.add_option("-g", "--gain", type="eng_float", default=20, - help="set gain in dB [default=%default]") - parser.add_option("-F", "--filter", action="store_true", default=True, - help="Enable channel filter") - (options, args) = parser.parse_args() - - if len(args) != 0: - parser.print_help() - raise SystemExit - - nchan = 4 - - if options.filter: - sw_decim = 4 - else: - sw_decim = 1 - - self.u = usrp.source_c(0, options.decim, fpga_filename="std_4rx_0tx.rbf") - if self.u.nddcs() < nchan: - sys.stderr.write('This code requires an FPGA build with %d DDCs. This FPGA has only %d.\n' % ( - nchan, self.u.nddcs())) - raise SystemExit - - if not self.u.set_nchannels(nchan): - sys.stderr.write('set_nchannels(%d) failed\n' % (nchan,)) - raise SystemExit - - input_rate = self.u.adc_freq() / self.u.decim_rate() - print "USB data rate = %s" % (eng_notation.num_to_str(input_rate),) - print "Scope data rate = %s" % (eng_notation.num_to_str(input_rate/sw_decim),) - - self.subdev = self.u.db(0) + self.u.db(1) - - if (len(self.subdev) < 4 or - self.u.db(0, 0).dbid() != usrp_dbid.BASIC_RX or - self.u.db(0, 0).dbid() != usrp_dbid.BASIC_RX): - sys.stderr.write('This code requires a Basic Rx board on Sides A & B\n') - sys.exit(1) - - self.u.set_mux(gru.hexint(0xf3f2f1f0)) - - # deinterleave four channels from FPGA - di = gr.deinterleave(gr.sizeof_gr_complex) - - self.connect(self.u, di) - - # our destination (8 float inputs) - self.scope = scopesink2.scope_sink_f(panel, sample_rate=input_rate/sw_decim, - num_inputs=2*nchan) - - # taps for channel filter - chan_filt_coeffs = optfir.low_pass (1, # gain - input_rate, # sampling rate - 80e3, # passband cutoff - 115e3, # stopband cutoff - 0.1, # passband ripple - 60) # stopband attenuation - #print len(chan_filt_coeffs) - - # bust the deinterleaved complex channels into floats - for i in range(nchan): - - if options.filter: - chan_filt = gr.fir_filter_ccf(sw_decim, chan_filt_coeffs) - c2f = gr.complex_to_float() - self.connect((di, i), chan_filt, c2f) - else: - c2f = gr.complex_to_float() - self.connect((di, i), c2f) - - self.connect((c2f, 0), (self.scope, 2*i + 0)) - self.connect((c2f, 1), (self.scope, 2*i + 1)) - - - self._build_gui(vbox) - - self.set_gain(options.gain) - self.set_freq(options.freq) - - def set_gain(self, gain): - for i in range(len(self.subdev)): - self.subdev[i].set_gain(gain) - - def set_freq(self, target_freq): - ok = True - for i in range(len(self.subdev)): - r = usrp.tune(self.u, i, self.subdev[i], target_freq) - if not r: - ok = False - print "set_freq: failed to set subdev[%d] freq to %f" % ( - i, target_freq) - - return ok - - - def _build_gui(self, vbox): - vbox.Add(self.scope.win, 10, wx.EXPAND) - - - -def main (): - app = stdgui2.stdapp(my_top_block, "Multi Scope", nstatus=1) - app.MainLoop() - -if __name__ == '__main__': - main () diff --git a/gr-uhd/examples/usrp_am_mw_rcv.py b/gr-uhd/examples/usrp_am_mw_rcv.py index 130bdcf56..a4fba9f0e 100755 --- a/gr-uhd/examples/usrp_am_mw_rcv.py +++ b/gr-uhd/examples/usrp_am_mw_rcv.py @@ -38,9 +38,8 @@ class wfm_rx_block (stdgui2.std_top_block): stdgui2.std_top_block.__init__ (self, frame, panel, vbox, argv) parser=OptionParser(option_class=eng_option) - parser.add_option("-a", "--address", type="string", - default="addr=192.168.10.2", - help="Address of UHD device, [default=%default]") + parser.add_option("-a", "--args", type="string", default="", + help="UHD device address args [default=%default]") 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, @@ -74,7 +73,7 @@ class wfm_rx_block (stdgui2.std_top_block): self.freq = 0 # build graph - self.u = uhd.usrp_source(device_addr=options.address, + self.u = uhd.usrp_source(device_addr=options.args, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=1) diff --git a/gr-uhd/examples/usrp_nbfm_ptt.py b/gr-uhd/examples/usrp_nbfm_ptt.py index af3b132f4..1f8a72e79 100755 --- a/gr-uhd/examples/usrp_nbfm_ptt.py +++ b/gr-uhd/examples/usrp_nbfm_ptt.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2005,2007.2011 Free Software Foundation, Inc. +# Copyright 2005,2007,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -48,9 +48,8 @@ class ptt_block(stdgui2.std_top_block): self.space_bar_pressed = False parser = OptionParser (option_class=eng_option) - parser.add_option("-a", "--address", type="string", - default="addr=192.168.10.2", - help="Address of UHD device, [default=%default]") + parser.add_option("-a", "--args", type="string", default="", + help="UHD device address args [default=%default]") parser.add_option("-A", "--antenna", type="string", default=None, help="select Rx Antenna where appropriate") parser.add_option ("-f", "--freq", type="eng_float", default=442.1e6, @@ -73,9 +72,9 @@ class ptt_block(stdgui2.std_top_block): if options.freq < 1e6: options.freq *= 1e6 - self.txpath = transmit_path(options.address, options.tx_gain, + self.txpath = transmit_path(options.args, options.tx_gain, options.audio_input) - self.rxpath = receive_path(options.address, options.rx_gain, + self.rxpath = receive_path(options.args, options.rx_gain, options.audio_output) self.connect(self.txpath) self.connect(self.rxpath) @@ -273,12 +272,12 @@ class ptt_block(stdgui2.std_top_block): # //////////////////////////////////////////////////////////////////////// class transmit_path(gr.hier_block2): - def __init__(self, address, gain, audio_input): + def __init__(self, args, gain, audio_input): gr.hier_block2.__init__(self, "transmit_path", gr.io_signature(0, 0, 0), # Input signature gr.io_signature(0, 0, 0)) # Output signature - self.u = uhd.usrp_sink(device_addr=address, + self.u = uhd.usrp_sink(device_addr=args, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=1) @@ -361,12 +360,12 @@ class transmit_path(gr.hier_block2): # //////////////////////////////////////////////////////////////////////// class receive_path(gr.hier_block2): - def __init__(self, address, gain, audio_output): + def __init__(self, args, gain, audio_output): gr.hier_block2.__init__(self, "receive_path", gr.io_signature(0, 0, 0), # Input signature gr.io_signature(0, 0, 0)) # Output signature - self.u = uhd.usrp_source(device_addr=address, + self.u = uhd.usrp_source(device_addr=args, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=1) diff --git a/gr-uhd/examples/usrp_nbfm_rcv.py b/gr-uhd/examples/usrp_nbfm_rcv.py index 2dc69423c..829381e7a 100755 --- a/gr-uhd/examples/usrp_nbfm_rcv.py +++ b/gr-uhd/examples/usrp_nbfm_rcv.py @@ -38,9 +38,8 @@ class my_top_block (stdgui2.std_top_block): stdgui2.std_top_block.__init__ (self,frame,panel,vbox,argv) parser=OptionParser(option_class=eng_option) - parser.add_option("-a", "--address", type="string", - default="addr=192.168.10.2", - help="Address of UHD device, [default=%default]") + parser.add_option("-a", "--args", type="string", default="", + help="UHD device address args [default=%default]") parser.add_option("-A", "--antenna", type="string", default=None, help="select Rx Antenna where appropriate") parser.add_option("-f", "--freq", type="eng_float", default=146.585e6, @@ -68,7 +67,7 @@ class my_top_block (stdgui2.std_top_block): self.freq = 0 self.freq_step = 25e3 - self.rxpath = receive_path(options.address, options.antenna, + self.rxpath = receive_path(options.args, options.antenna, options.gain, options.audio_output) self.connect(self.rxpath) @@ -260,12 +259,12 @@ class my_top_block (stdgui2.std_top_block): USE_SIMPLE_SQUELCH = False class receive_path(gr.hier_block2): - def __init__(self, address, antenna, gain, audio_output): + def __init__(self, args, antenna, gain, audio_output): gr.hier_block2.__init__(self, "receive_path", gr.io_signature(0, 0, 0), # Input signature gr.io_signature(0, 0, 0)) # Output signature - self.u = uhd.usrp_source(device_addr=address, + self.u = uhd.usrp_source(device_addr=args, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=1) diff --git a/gr-uhd/examples/usrp_spectrum_sense.py b/gr-uhd/examples/usrp_spectrum_sense.py index e89745b3b..cf41e7043 100755 --- a/gr-uhd/examples/usrp_spectrum_sense.py +++ b/gr-uhd/examples/usrp_spectrum_sense.py @@ -84,9 +84,8 @@ class my_top_block(gr.top_block): usage = "usage: %prog [options] min_freq max_freq" parser = OptionParser(option_class=eng_option, usage=usage) - parser.add_option("-a", "--address", type="string", - default="addr=192.168.10.2", - help="Address of UHD device, [default=%default]") + parser.add_option("-a", "--args", type="string", default="", + help="UHD device device address args [default=%default]") 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, @@ -130,7 +129,7 @@ class my_top_block(gr.top_block): print "Note: failed to enable realtime scheduling" # build graph - self.u = uhd.usrp_source(device_addr=options.address, + self.u = uhd.usrp_source(device_addr=options.args, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=1) diff --git a/gr-uhd/examples/usrp_tv_rcv.py b/gr-uhd/examples/usrp_tv_rcv.py index a68867365..2ad1f2122 100755 --- a/gr-uhd/examples/usrp_tv_rcv.py +++ b/gr-uhd/examples/usrp_tv_rcv.py @@ -62,9 +62,8 @@ class tv_rx_block (stdgui2.std_top_block): usage="%prog: [options] [input_filename]. \n If you don't specify an input filename the usrp will be used as source\n " \ "Make sure your input capture file containes interleaved shorts not complex floats" parser=OptionParser(option_class=eng_option, usage=usage) - parser.add_option("-a", "--address", type="string", - default="addr=192.168.10.2", - help="Address of UHD device, [default=%default]") + parser.add_option("-a", "--args", type="string", default="", + help="UHD device address args [default=%default]") 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, @@ -130,7 +129,7 @@ class tv_rx_block (stdgui2.std_top_block): self.gain=0.0 else: # use a UHD device - self.u = uhd.usrp_source(device_addr=options.address, + self.u = uhd.usrp_source(device_addr=options.args, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=1) diff --git a/gr-uhd/examples/usrp_tv_rcv_nogui.py b/gr-uhd/examples/usrp_tv_rcv_nogui.py index a44e20d39..3fe426fbc 100755 --- a/gr-uhd/examples/usrp_tv_rcv_nogui.py +++ b/gr-uhd/examples/usrp_tv_rcv_nogui.py @@ -59,9 +59,8 @@ class my_top_block(gr.top_block): "Make sure your input capture file containes interleaved " + \ "shorts not complex floats") parser = OptionParser(option_class=eng_option, usage=usage) - parser.add_option("-a", "--address", type="string", - default="addr=192.168.10.2", - help="Address of UHD device, [default=%default]") + parser.add_option("-a", "--args", type="string", default="", + help="UHD device address args [default=%default]") 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, @@ -130,7 +129,7 @@ class my_top_block(gr.top_block): raise SystemExit, 1 # build the graph - self.u = uhd.usrp_source(device_addr=options.address, + self.u = uhd.usrp_source(device_addr=options.args, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=1) diff --git a/gr-uhd/examples/usrp_wfm_rcv.py b/gr-uhd/examples/usrp_wfm_rcv.py index 7b35fbbe4..138e5045b 100755 --- a/gr-uhd/examples/usrp_wfm_rcv.py +++ b/gr-uhd/examples/usrp_wfm_rcv.py @@ -34,9 +34,8 @@ class wfm_rx_block (stdgui2.std_top_block): stdgui2.std_top_block.__init__ (self,frame,panel,vbox,argv) parser=OptionParser(option_class=eng_option) - parser.add_option("-a", "--address", type="string", - default="addr=192.168.10.2", - help="Address of UHD device, [default=%default]") + parser.add_option("-a", "--args", type="string", default="", + help="UHD device address args [default=%default]") parser.add_option("-A", "--antenna", type="string", default=None, help="select Rx Antenna where appropriate") parser.add_option("-f", "--freq", type="eng_float", default=100.1e6, @@ -68,7 +67,7 @@ class wfm_rx_block (stdgui2.std_top_block): self.fm_freq_max = options.freq_max # build graph - self.u = uhd.usrp_source(device_addr=options.address, + self.u = uhd.usrp_source(device_addr=options.args, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=1) diff --git a/gr-uhd/examples/usrp_wfm_rcv2_nogui.py b/gr-uhd/examples/usrp_wfm_rcv2_nogui.py index 013a6864f..13f89c71c 100755 --- a/gr-uhd/examples/usrp_wfm_rcv2_nogui.py +++ b/gr-uhd/examples/usrp_wfm_rcv2_nogui.py @@ -33,9 +33,8 @@ class wfm_rx_block (gr.top_block): gr.top_block.__init__(self) parser=OptionParser(option_class=eng_option) - parser.add_option("-a", "--address", type="string", - default="addr=192.168.10.2", - help="Address of UHD device, [default=%default]") + parser.add_option("-a", "--args", type="string", default="", + help="UHD device address args [default=%default]") parser.add_option("-A", "--antenna", type="string", default=None, help="select Rx Antenna where appropriate") parser.add_option("", "--f1", type="eng_float", default=100.7e6, @@ -69,7 +68,7 @@ class wfm_rx_block (gr.top_block): self.fm_freq_max = options.freq_max # build graph - self.u = uhd.usrp_source(device_addr=options.address, + self.u = uhd.usrp_source(device_addr=options.args, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=2) diff --git a/gr-uhd/examples/usrp_wfm_rcv_fmdet.py b/gr-uhd/examples/usrp_wfm_rcv_fmdet.py index 53ad6edbf..d13ebe829 100755 --- a/gr-uhd/examples/usrp_wfm_rcv_fmdet.py +++ b/gr-uhd/examples/usrp_wfm_rcv_fmdet.py @@ -28,18 +28,13 @@ from optparse import OptionParser import sys import wx -import os -print os.getpid() -raw_input() - class wfm_rx_block (stdgui2.std_top_block): def __init__(self,frame,panel,vbox,argv): stdgui2.std_top_block.__init__ (self,frame,panel,vbox,argv) parser=OptionParser(option_class=eng_option) - parser.add_option("-a", "--address", type="string", - default="addr=192.168.10.2", - help="Address of UHD device, [default=%default]") + parser.add_option("-a", "--args", type="string", default="", + help="UHD device address args [default=%default]") parser.add_option("-A", "--antenna", type="string", default=None, help="select Rx Antenna where appropriate") parser.add_option("-f", "--freq", type="eng_float", default=100.1e6, @@ -74,7 +69,7 @@ class wfm_rx_block (stdgui2.std_top_block): self.fm_freq_max = options.freq_max # build graph - self.u = uhd.usrp_source(device_addr=options.address, + self.u = uhd.usrp_source(device_addr=options.args, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=1) diff --git a/gr-uhd/examples/usrp_wfm_rcv_nogui.py b/gr-uhd/examples/usrp_wfm_rcv_nogui.py index ffeda4493..7c2c6050d 100755 --- a/gr-uhd/examples/usrp_wfm_rcv_nogui.py +++ b/gr-uhd/examples/usrp_wfm_rcv_nogui.py @@ -32,9 +32,8 @@ class wfm_rx_block (gr.top_block): gr.top_block.__init__(self) parser=OptionParser(option_class=eng_option) - parser.add_option("-a", "--address", type="string", - default="addr=192.168.10.2", - help="Address of UHD device, [default=%default]") + parser.add_option("-a", "--args", type="string", default="", + help="UHD device address args [default=%default]") parser.add_option("-A", "--antenna", type="string", default=None, help="select Rx Antenna where appropriate") parser.add_option("-f", "--freq", type="eng_float", default=100.1e6, @@ -62,7 +61,7 @@ class wfm_rx_block (gr.top_block): self.fm_freq_max = options.freq_max # build graph - self.u = uhd.usrp_source(device_addr=options.address, + self.u = uhd.usrp_source(device_addr=options.args, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=1) diff --git a/gr-uhd/examples/usrp_wfm_rcv_pll.py b/gr-uhd/examples/usrp_wfm_rcv_pll.py index 2cb4e4068..78c05e057 100755 --- a/gr-uhd/examples/usrp_wfm_rcv_pll.py +++ b/gr-uhd/examples/usrp_wfm_rcv_pll.py @@ -34,9 +34,8 @@ class wfm_rx_block (stdgui2.std_top_block): stdgui2.std_top_block.__init__ (self,frame,panel,vbox,argv) parser=OptionParser(option_class=eng_option) - parser.add_option("-a", "--address", type="string", - default="addr=192.168.10.2", - help="Address of UHD device, [default=%default]") + parser.add_option("-a", "--args", type="string", default="", + help="UHD device address args [default=%default]") parser.add_option("-A", "--antenna", type="string", default=None, help="select Rx Antenna where appropriate") parser.add_option("-f", "--freq", type="eng_float", default=100.1e6, @@ -70,7 +69,7 @@ class wfm_rx_block (stdgui2.std_top_block): self.fm_freq_max = options.freq_max # build graph - self.u = uhd.usrp_source(device_addr=options.address, + self.u = uhd.usrp_source(device_addr=options.args, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=1) diff --git a/gr-uhd/examples/usrp_wfm_rcv_sca.py b/gr-uhd/examples/usrp_wfm_rcv_sca.py index 1c6154871..f0f6aec66 100755 --- a/gr-uhd/examples/usrp_wfm_rcv_sca.py +++ b/gr-uhd/examples/usrp_wfm_rcv_sca.py @@ -64,9 +64,8 @@ class wfm_rx_sca_block (stdgui2.std_top_block): stdgui2.std_top_block.__init__ (self,frame,panel,vbox,argv) parser=OptionParser(option_class=eng_option) - parser.add_option("-a", "--address", type="string", - default="addr=192.168.10.2", - help="Address of UHD device, [default=%default]") + parser.add_option("-a", "--args", type="string", default="", + help="UHD device address args [default=%default]") parser.add_option("-A", "--antenna", type="string", default=None, help="select Rx Antenna where appropriate") parser.add_option("-f", "--freq", type="eng_float", default=100.1e6, @@ -99,7 +98,7 @@ class wfm_rx_sca_block (stdgui2.std_top_block): # build graph - self.u = uhd.usrp_source(device_addr=options.address, + self.u = uhd.usrp_source(device_addr=options.args, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=1) diff --git a/gr-uhd/examples/usrp_wxapt_rcv.py b/gr-uhd/examples/usrp_wxapt_rcv.py index 5b44398d1..809756d96 100755 --- a/gr-uhd/examples/usrp_wxapt_rcv.py +++ b/gr-uhd/examples/usrp_wxapt_rcv.py @@ -34,9 +34,8 @@ class wxapt_rx_block (stdgui2.std_top_block): stdgui2.std_top_block.__init__ (self,frame,panel,vbox,argv) parser=OptionParser(option_class=eng_option) - parser.add_option("-a", "--address", type="string", - default="addr=192.168.10.2", - help="Address of UHD device, [default=%default]") + parser.add_option("-a", "--args", type="string", default="", + help="UHD device address args, [default=%default]") parser.add_option("-A", "--antenna", type="string", default=None, help="select Rx Antenna where appropriate") parser.add_option("-f", "--freq", type="eng_float", default=137.5e6, @@ -68,7 +67,7 @@ class wxapt_rx_block (stdgui2.std_top_block): self.freq_max = options.freq_max # build graph - self.u = uhd.usrp_source(device_addr=options.address, + self.u = uhd.usrp_source(device_addr=options.args, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=1) diff --git a/gr-uhd/swig/__init__.py b/gr-uhd/swig/__init__.py index c63d3cc57..7745b4b79 100644 --- a/gr-uhd/swig/__init__.py +++ b/gr-uhd/swig/__init__.py @@ -69,6 +69,15 @@ def _prepare_uhd_swig(): if hasattr(myobj, 'to_real'): myobj.__float__ = lambda o: o.to_real() if attr.endswith('_t'): setattr(uhd_swig, attr[:-2], myobj) + #make a new find devices that casts everything with the pythonized device_addr_t which has __str__ + def find_devices(*args, **kwargs): + def to_pythonized_dev_addr(dev_addr): + new_dev_addr = uhd_swig.device_addr_t() + for key in dev_addr.keys(): new_dev_addr[key] = dev_addr.get(key) + return new_dev_addr + return map(to_pythonized_dev_addr, uhd_swig.find_devices_raw(*args, **kwargs)) + setattr(uhd_swig, 'find_devices', find_devices) + #Cast constructor args (FIXME swig handle overloads?) for attr in ('usrp_source', 'usrp_sink', 'amsg_source'): def constructor_factory(old_constructor): diff --git a/gr-uhd/swig/uhd_swig.i b/gr-uhd/swig/uhd_swig.i index f8381ae64..7e612907c 100644 --- a/gr-uhd/swig/uhd_swig.i +++ b/gr-uhd/swig/uhd_swig.i @@ -102,6 +102,17 @@ GR_SWIG_BLOCK_MAGIC(uhd,amsg_source) %include <gr_uhd_amsg_source.h> //////////////////////////////////////////////////////////////////////// +// device discovery (no need to %include device.hpp) +//////////////////////////////////////////////////////////////////////// +%{ +static uhd::device_addrs_t find_devices_raw(const uhd::device_addr_t &dev_addr = uhd::device_addr_t()){ + return uhd::device::find(dev_addr); +} +%} + +static uhd::device_addrs_t find_devices_raw(const uhd::device_addr_t &dev_addr = uhd::device_addr_t()); + +//////////////////////////////////////////////////////////////////////// // helpful constants //////////////////////////////////////////////////////////////////////// %{ diff --git a/grc/grc_gnuradio/README b/grc/grc_gnuradio/README index 5a89da54a..897eed65c 100644 --- a/grc/grc_gnuradio/README +++ b/grc/grc_gnuradio/README @@ -7,8 +7,5 @@ The blk2s module wraps many blocks in blks2 and gives them streaming outputs. Will be phased-out by new message passing implementations. Other blks2 blocks will hopefully make their way into blks2impl. -The usrp module contains the simple and dual usrp wrappers. -Will be phased-out by generic usrp and/or new usrp api. - The wxgui module contains a top_block + wxgui frame. Will be phased-out by gui.py in wxgui and a new top block template. diff --git a/grc/python/extract_docs.py b/grc/python/extract_docs.py index be55fd239..fe157a221 100644 --- a/grc/python/extract_docs.py +++ b/grc/python/extract_docs.py @@ -26,7 +26,7 @@ DOXYGEN_NAME_XPATH = '/doxygen/compounddef/compoundname' DOXYGEN_BRIEFDESC_GR_XPATH = '/doxygen/compounddef/briefdescription' DOXYGEN_DETAILDESC_GR_XPATH = '/doxygen/compounddef/detaileddescription' -GROUP_KEYS = "gr|usrp2|trellis|noaa|vocoder|digital" +GROUP_KEYS = "gr|trellis|noaa|vocoder|digital" def extract_txt(xml): """ @@ -65,7 +65,6 @@ def _extract(key): #extract descriptions comp_name = extract_txt(xml.xpath(DOXYGEN_NAME_XPATH)[0]).strip() comp_name = ' --- ' + comp_name + ' --- ' -# if re.match('(gr|usrp2|trellis|noaa)_.*', key): if re.match(('(%s)_.*' % GROUP_KEYS), key): brief_desc = extract_txt(xml.xpath(DOXYGEN_BRIEFDESC_GR_XPATH)[0]).strip() detailed_desc = extract_txt(xml.xpath(DOXYGEN_DETAILDESC_GR_XPATH)[0]).strip() diff --git a/grc/todo.txt b/grc/todo.txt index 9dad05730..ccfaad72a 100644 --- a/grc/todo.txt +++ b/grc/todo.txt @@ -9,19 +9,14 @@ ################################################## * probe: also non-float outputs * log slider gui control -* generic usrp (when its ready) * packet mod: whitening offset * wx min window size in options block * gr_adaptive_fir_ccf * ofdm * gr_ofdm_bpsk_demapper - * gr_ofdm_cyclic_prefixer * gr_ofdm_demapper_vcb - * gr_ofdm_frame_acquisition * gr_ofdm_frame_sink - * gr_ofdm_insert_preamble * gr_ofdm_mapper_bcv - * gr_ofdm_sampler * size params for the graphical sinks * callbacks for set average on fft, waterfall, number sinks * add units to params: Sps, Hz, dB... diff --git a/gruel/README b/gruel/README index 585cf026a..647dc843b 100644 --- a/gruel/README +++ b/gruel/README @@ -22,9 +22,8 @@ The GNU Radio Utility Etcetera Library, a collection of low-level routines to avoid dependencies on the full GNU Radio core or other libraries. -Over time, some code from libgnuradio-core, libpmt, libmblock, libusrp, -and libusrp2 will migrate here, to avoid duplication of code and simplify -dependencies. +Over time, some code from libgnuradio-core and libpmt will migrate +here, to avoid duplication of code and simplify dependencies. By design, this library will not have dependencies on any other part of GNU Radio, but may have external dependencies such as Boost. |