aboutsummaryrefslogtreecommitdiffstats
path: root/tools/gr-usrptest/python/functions.py
diff options
context:
space:
mode:
authorAndrej Rode <andrej.rode@ettus.com>2016-10-24 10:25:42 -0700
committerMartin Braun <martin.braun@ettus.com>2017-05-26 16:01:37 -0700
commit76e9e6393fe1d5a0ccc9e05deb431694921850ec (patch)
treeb7f1097a04fd7a7d0a423a353fbeba037746b782 /tools/gr-usrptest/python/functions.py
parent06ff34eaa9e147b11d2698308fa91a5260fee2d2 (diff)
downloaduhd-76e9e6393fe1d5a0ccc9e05deb431694921850ec.tar.gz
uhd-76e9e6393fe1d5a0ccc9e05deb431694921850ec.tar.bz2
uhd-76e9e6393fe1d5a0ccc9e05deb431694921850ec.zip
gr-usrptest: Initial creation
- new OOT-blocks: phase_calc_ccf hier-block, measurement_sink_f - new python submodules: flowgraphs, functions, rts_tests - new apps: usrp_phasealignment.py - cmdline example for manual testing OOT-Blocks: - phase_calc_ccf takes two complex input streams and conjugate multiplys them and extracts the phase from the result and converts it to degree scale - measurement_sink_f: takes a float input stream and calculates average and stddev for a specified number of samples. Start of a measurement is invoked by a call of start_run() on the block. After a couple of runs average and stddev can be extracted. Python modules: - flowgrahps contains reconfigurable flowgraphs for different GNU Radio RF test cases - functions contains functions which are used in different apps/RTS scripts - rts_tests contains test cases which are meant to be executed from the RTS system. Depends on TinyDB, labview_automation Apps: - usrp_phasealignment.py is an example how to use the underlying flowgraph to measure phase differences. Commandline arguments of uhd_app can be used and several additional arguments can/have to be specified. Runs a phase difference measurement --runs number of times and averages phase difference over --duration seconds. Between measurements USRP sinks are retuned to random frequencies in daughterboard range. Results are displayed using motherboard serial and daughterboard serial
Diffstat (limited to 'tools/gr-usrptest/python/functions.py')
-rw-r--r--tools/gr-usrptest/python/functions.py133
1 files changed, 133 insertions, 0 deletions
diff --git a/tools/gr-usrptest/python/functions.py b/tools/gr-usrptest/python/functions.py
new file mode 100644
index 000000000..e3f7958b1
--- /dev/null
+++ b/tools/gr-usrptest/python/functions.py
@@ -0,0 +1,133 @@
+#!/usr/bin/env python2
+import numpy as np
+import time
+import copy
+import logging
+
+
+def setup_phase_alignment_parser(parser):
+ test_group = parser.add_argument_group(
+ 'Phase alignment specific arguments')
+ test_group.add_argument(
+ '--runs',
+ default=10,
+ type=int,
+ help='Number of times to retune and measure d_phi')
+ test_group.add_argument(
+ '--duration',
+ default=5.0,
+ type=float,
+ help='Duration of a measurement run')
+ test_group.add_argument(
+ '--measurement-setup',
+ type=str,
+ help='Comma-seperated list of channel ids. Phase difference will be calculated between consecutive channels. default=(0,1,2,..,M-1) M: num_chan'
+ )
+ test_group.add_argument(
+ '--log-level',
+ type=str,
+ choices=["critical", "error", "warning", "info", "debug"],
+ default="info")
+ test_group.add_argument(
+ '--freq-bands',
+ type=int,
+ help="Number of frequency bands in daughterboard range to randomly retune to",
+ default=1)
+ return parser
+
+
+def setup_tx_phase_alignment_parser(parser):
+ tx_group = parser.add_argument_group(
+ 'TX Phase alignment specific arguments.')
+ tx_group.add_argument(
+ '--tx-channels', type=str, help='which channels to use')
+ tx_group.add_argument(
+ '--tx-antenna',
+ type=str,
+ help='comma-separated list of channel antennas for tx')
+ tx_group.add_argument(
+ '--tx-offset',
+ type=float,
+ help='frequency offset in Hz which should be added to center frequency for transmission'
+ )
+ return parser
+
+
+def setup_rts_phase_alignment_parser(parser):
+ rts_group = parser.add_argument_group('RTS Phase alignment specific arguments')
+ rts_group.add_argument(
+ '-pd', '--phasedev',
+ type=float,
+ default=1.0,
+ help='maximum phase standard deviation of dphi in a run which is considered settled (in deg)')
+ rts_group.add_argument(
+ '-dp',
+ '--dphi',
+ type=float,
+ default=2.0,
+ help='maximum allowed d_phase deviation between runs (in deg)')
+ return parser
+
+def setup_manual_phase_alignment_parser(parser):
+ manual_group = parser.add_argument_group(
+ 'Manual Phase alignment specific arguments')
+ manual_group.add_argument(
+ '--plot',
+ dest='plot',
+ action='store_true',
+ help='Set this argument to enable plotting results with matplotlib'
+ )
+ manual_group.add_argument(
+ '--auto',
+ action='store_true',
+ help='Set this argument to enable automatic selection of test frequencies'
+ )
+ manual_group.add_argument(
+ '--start-freq',
+ type=float,
+ default=0.0,
+ help='Start frequency for automatic selection'
+ ),
+ manual_group.add_argument(
+ '--stop-freq',
+ type=float,
+ default=0.0,
+ help='Stop frequency for automatic selection')
+
+ parser.set_defaults(plot=False,auto=False)
+ return parser
+
+
+def process_measurement_sinks(top_block):
+ data = list()
+ curr_data = dict()
+ for num, chan in enumerate(top_block.measurement_channels[:-1]):
+ curr_data['avg'] = list(top_block.measurement_sink[num].get_avg())
+ curr_data['stddev'] = list(top_block.measurement_sink[num].get_stddev(
+ ))
+ curr_data['first'] = top_block.measurement_channels_names[num]
+ curr_data['second'] = top_block.measurement_channels_names[num + 1]
+ data.append(copy.copy(curr_data))
+ return data
+
+
+def run_test(top_block, ntimes):
+ results = dict()
+ num_sinks = len(top_block.measurement_sink)
+ for i in xrange(ntimes):
+ #tune frequency to random position and back to specified frequency
+ top_block.retune_frequency(bands=top_block.uhd_app.args.freq_bands,band_num=i+1)
+ time.sleep(2)
+ #trigger start in all measurement_sinks
+ for sink in top_block.measurement_sink:
+ sink.start_run()
+ #wait until every measurement_sink is ready with the current run
+ while (sum([ms.get_run() for ms in top_block.measurement_sink]) < (
+ (i + 1) * num_sinks)):
+ time.sleep(1)
+ results = process_measurement_sinks(top_block)
+ return results
+
+
+def log_level(string):
+ return getattr(logging, string.upper())