summaryrefslogtreecommitdiff
path: root/gr-radar/src/python
diff options
context:
space:
mode:
authorjcorgan2006-08-03 04:51:51 +0000
committerjcorgan2006-08-03 04:51:51 +0000
commit5d69a524f81f234b3fbc41d49ba18d6f6886baba (patch)
treeb71312bf7f1e8d10fef0f3ac6f28784065e73e72 /gr-radar/src/python
downloadgnuradio-5d69a524f81f234b3fbc41d49ba18d6f6886baba.tar.gz
gnuradio-5d69a524f81f234b3fbc41d49ba18d6f6886baba.tar.bz2
gnuradio-5d69a524f81f234b3fbc41d49ba18d6f6886baba.zip
Houston, we have a trunk.
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@3122 221aa14e-8319-0410-a670-987f0aec2ac5
Diffstat (limited to 'gr-radar/src/python')
-rw-r--r--gr-radar/src/python/Makefile.am33
-rwxr-xr-xgr-radar/src/python/complex_to_short.py33
-rwxr-xr-xgr-radar/src/python/fm_demod_file.py66
-rwxr-xr-xgr-radar/src/python/gen_fm_signal.py66
-rwxr-xr-xgr-radar/src/python/gen_random_signal.py66
-rwxr-xr-xgr-radar/src/python/qa_nothing.py0
-rw-r--r--gr-radar/src/python/run_tests.in47
-rwxr-xr-xgr-radar/src/python/signal_levels.py62
-rwxr-xr-xgr-radar/src/python/split_files.py93
-rwxr-xr-xgr-radar/src/python/usrp_rx_radar.py89
10 files changed, 555 insertions, 0 deletions
diff --git a/gr-radar/src/python/Makefile.am b/gr-radar/src/python/Makefile.am
new file mode 100644
index 000000000..da81410f4
--- /dev/null
+++ b/gr-radar/src/python/Makefile.am
@@ -0,0 +1,33 @@
+#
+# 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 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST = run_tests.in
+
+
+TESTS = \
+ run_tests
+
+
+noinst_PYTHON = \
+ qa_nothing.py \
+ usrp_rx_radar.py
diff --git a/gr-radar/src/python/complex_to_short.py b/gr-radar/src/python/complex_to_short.py
new file mode 100755
index 000000000..9c229d857
--- /dev/null
+++ b/gr-radar/src/python/complex_to_short.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, eng_notation, optfir
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import os.path
+import re
+
+class my_graph(gr.flow_graph):
+ def __init__(self):
+ gr.flow_graph.__init__(self)
+
+ usage="%prog: [options] input_file output_file"
+ parser = OptionParser (option_class=eng_option, usage=usage)
+ (options, args) = parser.parse_args()
+ if len(args) != 2:
+ parser.print_help()
+ raise SystemExit, 1
+
+ input_filename = args[0]
+ output_filename = args[1]
+
+ inf = gr.file_source(gr.sizeof_gr_complex, input_filename)
+ c2s = gr.complex_to_interleaved_short()
+ outf = gr.file_sink(gr.sizeof_short, output_filename)
+ self.connect(inf, c2s, outf)
+
+
+if __name__ == '__main__':
+ try:
+ my_graph().run()
+ except KeyboardInterrupt:
+ pass
diff --git a/gr-radar/src/python/fm_demod_file.py b/gr-radar/src/python/fm_demod_file.py
new file mode 100755
index 000000000..9d430a892
--- /dev/null
+++ b/gr-radar/src/python/fm_demod_file.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+#
+# Copyright 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 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+"""
+Demod FM signal in data collected for radar.
+Input samples are complex baseband, 250kS/sec.
+"""
+
+from gnuradio import gr, gru, blks, eng_notation
+from gnuradio import audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import sys
+import math
+
+
+class my_graph(gr.flow_graph):
+ def __init__(self, input_filename, repeat):
+ gr.flow_graph.__init__(self)
+
+ baseband_rate = 250e3
+ audio_decim = 8
+ audio_rate = int(baseband_rate // audio_decim) # output is at 31250 S/s
+
+ src = gr.file_source(gr.sizeof_gr_complex, input_filename, repeat)
+ guts = blks.wfm_rcv(self, baseband_rate, audio_decim)
+ sink = audio.sink(audio_rate, "plughw:0,0")
+ self.connect(src, guts, sink)
+
+def main ():
+ usage = "usage: %prog [options] filename"
+ parser = OptionParser (option_class=eng_option, usage=usage)
+ parser.add_option ("-r", "--repeat", action="store_true", default=False)
+ (options, args) = parser.parse_args ()
+
+ if len (args) != 1:
+ parser.print_help ()
+ sys.exit (1)
+
+ try:
+ my_graph(args[0], options.repeat).run()
+ except KeyboardInterrupt:
+ pass
+
+
+if __name__ == '__main__':
+ main ()
diff --git a/gr-radar/src/python/gen_fm_signal.py b/gr-radar/src/python/gen_fm_signal.py
new file mode 100755
index 000000000..cd0834aa1
--- /dev/null
+++ b/gr-radar/src/python/gen_fm_signal.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+#
+# Copyright 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 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+from gnuradio import gr, gru, blks, eng_notation
+from gnuradio import audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import sys
+import math
+
+
+class my_graph(gr.flow_graph):
+ def __init__(self, output_filename, tx_gain, nsamples):
+ gr.flow_graph.__init__(self)
+
+ audio_rate = 31250
+ baseband_rate = 250e3
+
+ src = gr.noise_source_f(gr.GR_GAUSSIAN, 1.0)
+ #src = gr.noise_source_f(gr.GR_GAUSSIAN, 0.5)
+ guts = blks.wfm_tx(self, audio_rate, baseband_rate)
+ amp = gr.multiply_const_cc(tx_gain)
+ head = gr.head(gr.sizeof_gr_complex, nsamples)
+ sink = gr.file_sink(gr.sizeof_gr_complex, output_filename)
+ self.connect(src, guts, amp, head, sink)
+
+def main ():
+ usage = "usage: %prog [options] output_filename"
+ parser = OptionParser (option_class=eng_option, usage=usage)
+ parser.add_option("-N", "--nsamples", type="eng_float", default=250000,
+ help="specify number of output samples to generate[=250000]")
+ parser.add_option("-g", "--tx-gain", type="eng_float", default=1.0,
+ help="specify transmitter gain[=1]")
+ (options, args) = parser.parse_args ()
+
+ if len (args) != 1:
+ parser.print_help ()
+ sys.exit (1)
+
+ try:
+ my_graph(args[0], options.tx_gain, int(options.nsamples)).run()
+ except KeyboardInterrupt:
+ pass
+
+
+if __name__ == '__main__':
+ main ()
diff --git a/gr-radar/src/python/gen_random_signal.py b/gr-radar/src/python/gen_random_signal.py
new file mode 100755
index 000000000..87a531c63
--- /dev/null
+++ b/gr-radar/src/python/gen_random_signal.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+#
+# Copyright 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 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+from gnuradio import gr, gru, blks, eng_notation
+from gnuradio import audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import sys
+import math
+
+
+class my_graph(gr.flow_graph):
+ def __init__(self, output_filename, tx_gain, nsamples):
+ gr.flow_graph.__init__(self)
+
+ audio_rate = 31250
+ baseband_rate = 250e3
+
+ src = gr.noise_source_c(gr.GR_GAUSSIAN, 1.0)
+ #src = gr.noise_source_f(gr.GR_GAUSSIAN, 0.5)
+ #guts = blks.wfm_tx(self, audio_rate, baseband_rate)
+ amp = gr.multiply_const_cc(tx_gain)
+ head = gr.head(gr.sizeof_gr_complex, nsamples)
+ sink = gr.file_sink(gr.sizeof_gr_complex, output_filename)
+ self.connect(src, amp, head, sink)
+
+def main ():
+ usage = "usage: %prog [options] output_filename"
+ parser = OptionParser (option_class=eng_option, usage=usage)
+ parser.add_option("-N", "--nsamples", type="eng_float", default=250000,
+ help="specify number of output samples to generate[=250000]")
+ parser.add_option("-g", "--tx-gain", type="eng_float", default=1.0,
+ help="specify transmitter gain[=1]")
+ (options, args) = parser.parse_args ()
+
+ if len (args) != 1:
+ parser.print_help ()
+ sys.exit (1)
+
+ try:
+ my_graph(args[0], options.tx_gain, int(options.nsamples)).run()
+ except KeyboardInterrupt:
+ pass
+
+
+if __name__ == '__main__':
+ main ()
diff --git a/gr-radar/src/python/qa_nothing.py b/gr-radar/src/python/qa_nothing.py
new file mode 100755
index 000000000..e69de29bb
--- /dev/null
+++ b/gr-radar/src/python/qa_nothing.py
diff --git a/gr-radar/src/python/run_tests.in b/gr-radar/src/python/run_tests.in
new file mode 100644
index 000000000..fd0a43ab2
--- /dev/null
+++ b/gr-radar/src/python/run_tests.in
@@ -0,0 +1,47 @@
+#!/bin/sh
+
+# All this strange PYTHONPATH manipulation is required to run our
+# tests using our just built shared library and swig-generated python
+# code prior to installation.
+
+# build tree == src tree unless you're doing a VPATH build.
+# If you don't know what a VPATH build is, you're not doing one. Relax...
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+
+# Where to look in the build tree for our shared library
+libbld=@abs_top_builddir@gr-radar/src/lib
+# Where to look in the src tree for swig generated python code
+libsrc=@abs_top_srcdir@/gr-radar/src/lib
+# Where to look in the src tree for hand written python code
+py=@abs_top_srcdir@/gr-radar/src/python
+
+# Where to look for GNU Radio python modules in current build tree
+# FIXME this is wrong on a distcheck. We really need to ask gnuradio-core
+# where it put its python files.
+grpythonbld=@abs_top_builddir@/gnuradio-core/src/python/:@abs_top_builddir@/gnuradio-core/src/lib/swig/:@abs_top_builddir@/gnuradio-core/src/lib/swig/.libs
+
+PYTHONPATH="$grpythonbld:$libbld:$libbld/.libs:$libsrc:$py:$PYTHONPATH"
+export PYTHONPATH
+
+#
+# This is the simple part...
+# Run everything that matches qa_*.py and return the final result.
+#
+
+ok=yes
+for file in @srcdir@/qa_*.py
+do
+ if ! $file
+ then
+ ok=no
+ fi
+done
+
+if [ $ok = yes ]
+then
+ exit 0
+else
+ exit 1
+fi
diff --git a/gr-radar/src/python/signal_levels.py b/gr-radar/src/python/signal_levels.py
new file mode 100755
index 000000000..f21f7f8bc
--- /dev/null
+++ b/gr-radar/src/python/signal_levels.py
@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+
+import sys
+from math import pi, log10
+from gnuradio.eng_notation import num_to_str
+
+def power_density(transmitted_power, distance):
+ """
+ Estimate power density in Watts/meter.
+ Assume isotropic radiator (spherical radiation pattern).
+
+ @param transmitted_power: Watts
+ @param distance: distance from transmitter in meters
+
+ """
+ return transmitted_power / (4 * pi * distance * distance)
+
+
+def ratio_of_target_return_to_direct(Rl, Rt, Rr, rcs):
+ """
+ Estimate relative strength of signal levels for direct and reflected
+ path in bistatic radar. Assume all antenna factors are constant,
+ and hence 'wash out'. Also assume that the antennas are isotropic
+ radiators (spherical radiation pattern).
+
+ @param Rl: distance between Tx and Rx in meters
+ @param Rt: distance between Tx and target in meters
+ @param Rr: distance between Rx and target in meters
+ @param rcs: radar cross section in meters^2
+
+ @returns: ratio of reflected to direct in decibels
+ """
+ Tx_power = 1
+ direct_path_power_density = power_density(Tx_power, Rl)
+ power_at_target = power_density(Tx_power, Rt) * rcs
+ reflected_path_power_density = power_density(power_at_target, Rr)
+ return 10*log10(reflected_path_power_density / direct_path_power_density)
+
+
+def print_header(f):
+ f.write(" Rl Rt Rr rcs dB\n")
+ f.write("-----------------------------------------\n")
+
+def print_result(f, Rl, Rt, Rr, rcs, dB):
+ f.write("%6sm %6sm %6sm %6s %6s\n" % tuple([num_to_str(x) for x in [Rl, Rt, Rr, rcs, dB]]))
+
+def calc_print(f, Rl, Rt, Rr, rcs):
+ print_result(f, Rl, Rt, Rr, rcs, ratio_of_target_return_to_direct(Rl, Rt, Rr, rcs))
+
+def main():
+ f = sys.stdout
+ print_header(f)
+ calc_print(f, 40e3, 100e3, 100e3, 10.0)
+ calc_print(f, 40e3, 80e3, 80e3, 10.0)
+ calc_print(f, 40e3, 40e3, 40e3, 10.0)
+ calc_print(f, 40e3, 40e3, 8e3, 10.0)
+ calc_print(f, 40e3, 60e3, 20e3, 10.0)
+ calc_print(f, 40e3, 20e3, 60e3, 10.0)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/gr-radar/src/python/split_files.py b/gr-radar/src/python/split_files.py
new file mode 100755
index 000000000..a604c0779
--- /dev/null
+++ b/gr-radar/src/python/split_files.py
@@ -0,0 +1,93 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, eng_notation, optfir
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import os.path
+import re
+
+plot = None
+
+def split_filename(src_filename):
+ s = os.path.splitext(src_filename)[0] # drop extension
+ date, time, freq, dec, nchan = s.split('-')
+ return (date, time, freq, int(dec), int(nchan))
+
+
+def make_filename(date, time, freq, n, short_output):
+ if short_output:
+ return '-'.join((date, time, freq)) + '.s%02d' % (n,)
+ else:
+ return '-'.join((date, time, freq)) + '.c%02d' % (n,)
+
+class my_graph(gr.flow_graph):
+
+ def __init__(self, src_filename, short_output):
+ """
+ Deinterleave file, filter and decimate by 4, and write out
+ a separate file for each input channel.
+
+ The input file is the raw output of nchannels of short USRP data.
+ That is, they are interleaved short I&Q for each channel.
+ """
+ global plot
+
+ gr.flow_graph.__init__(self)
+
+ decim = 4
+
+ (date, time, freq, dec, nchan) = split_filename(src_filename)
+
+ src = gr.file_source(gr.sizeof_short, src_filename)
+
+ # convert stream of interleaved shorts to a stream of complex
+ s2c = gr.interleaved_short_to_complex()
+
+ # deinterleave complexes into separate streams
+ deint = gr.deinterleave(gr.sizeof_gr_complex)
+
+ self.connect(src, s2c, deint)
+
+ taps = optfir.low_pass(1, # gain
+ 1, # sampling rate
+ 0.100, # passband cutoff
+ 0.125, # stopband cutoff
+ 0.01, # passband ripple (dB)
+ 70) # stopband atten (dB)
+
+ print "len(taps) =", len(taps)
+
+ #plot = gru.gnuplot_freqz(gru.freqz(taps, 1), 1)
+ #raw_input('Press Enter to continue: ')
+
+ for n in xrange(nchan):
+ #df = gr.fft_filter_ccc(decim, taps)
+ df = gr.fir_filter_ccf(decim, taps)
+ self.connect((deint, n), df)
+ dst_filename = make_filename(date, time, freq, n, short_output)
+ if short_output:
+ c2s = gr.complex_to_interleaved_short()
+ dst = gr.file_sink(gr.sizeof_short, dst_filename)
+ self.connect(df, c2s, dst)
+ else:
+ dst = gr.file_sink(gr.sizeof_gr_complex, dst_filename)
+ self.connect(df, dst)
+
+
+def split_1_file(filename, short_output):
+ my_graph(filename, short_output).run()
+
+
+def main():
+ usage="%prog: [options] file_to_split..."
+ parser = OptionParser (option_class=eng_option, usage=usage)
+ parser.add_option("-s", "--short", action="store_true", default=False,
+ help="short output if set, else complex")
+ (options, args) = parser.parse_args()
+
+ for filename in args:
+ split_1_file(filename, options.short)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/gr-radar/src/python/usrp_rx_radar.py b/gr-radar/src/python/usrp_rx_radar.py
new file mode 100755
index 000000000..e7c2da2c2
--- /dev/null
+++ b/gr-radar/src/python/usrp_rx_radar.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, eng_notation
+from gnuradio import usrp
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import usrp_dbid
+import time
+import os.path
+
+
+def make_filename(dir, freq, decim, nchan, suffix):
+ t = time.strftime('%Y%m%d-%H%M%S')
+ f = 'R%s-%s-%d-%d.%s' % (
+ t, eng_notation.num_to_str(freq), decim, nchan, suffix)
+ return os.path.join(dir, f)
+
+class radar_graph(gr.flow_graph):
+
+ def __init__(self):
+ gr.flow_graph.__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=64,
+ help="set fgpa decimation rate to DECIM (default=64)")
+ parser.add_option("-f", "--freq", type="eng_float", default=104.5e6,
+ help="set frequency to FREQ (default=104.5M)", metavar="FREQ")
+ parser.add_option("", "--gain0", type="eng_float", default=0,
+ help="set gain in dB (default 0)")
+ parser.add_option("", "--gain1", type="eng_float", default=11,
+ help="set gain in dB (default 11)")
+ parser.add_option("-F", "--filename", default=None)
+ parser.add_option("-D", "--dir", default=None)
+ (options, args) = parser.parse_args()
+
+ if len(args) != 0:
+ parser.print_help()
+ sys.exit(1)
+
+ if options.filename is None and options.dir is None:
+ sys.stderr.write('Must specify either -F FILENAME or -D DIR\n')
+ parser.print_help()
+ sys.exit(1)
+
+ nchan = 2
+
+ # if filename was given, use it, otherwise build one.
+ if options.filename is None:
+ options.filename = make_filename(options.dir, options.freq,
+ options.decim, nchan, 'srd')
+
+ self.u = usrp.source_s(0, options.decim, nchan, 0, 0)
+ self.subdev = self.u.db[0]
+
+ if self.u.db[0][0].dbid() != usrp_dbid.BASIC_RX:
+ sys.stderr.write('This code requires a Basic Rx board on Side A\n')
+ sys.exit(1)
+
+ # self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.subdev))
+ self.u.set_mux(gru.hexint(0xf0f0f1f0))
+
+ dst = gr.file_sink (gr.sizeof_short, options.filename)
+ self.connect (self.u, dst)
+
+ self.subdev[0].set_gain(options.gain0)
+ self.subdev[1].set_gain(options.gain1)
+ self.set_freq(options.freq)
+
+
+ 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
+
+
+if __name__ == '__main__':
+ fg = radar_graph()
+ try:
+ fg.run()
+ except KeyboardInterrupt:
+ pass