diff options
author | Andrej Rode <andrej.rode@ettus.com> | 2016-10-24 10:25:42 -0700 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2017-05-26 16:01:37 -0700 |
commit | 76e9e6393fe1d5a0ccc9e05deb431694921850ec (patch) | |
tree | b7f1097a04fd7a7d0a423a353fbeba037746b782 /tools/gr-usrptest/python/functions.py | |
parent | 06ff34eaa9e147b11d2698308fa91a5260fee2d2 (diff) | |
download | uhd-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.py | 133 |
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()) |