aboutsummaryrefslogtreecommitdiffstats
path: root/tools/gr-usrptest/python/rts_tests
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/rts_tests
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/rts_tests')
-rw-r--r--tools/gr-usrptest/python/rts_tests/CMakeLists.txt27
-rw-r--r--tools/gr-usrptest/python/rts_tests/__init__.py14
-rw-r--r--tools/gr-usrptest/python/rts_tests/test_phasealignment.py121
3 files changed, 162 insertions, 0 deletions
diff --git a/tools/gr-usrptest/python/rts_tests/CMakeLists.txt b/tools/gr-usrptest/python/rts_tests/CMakeLists.txt
new file mode 100644
index 000000000..fbe49995a
--- /dev/null
+++ b/tools/gr-usrptest/python/rts_tests/CMakeLists.txt
@@ -0,0 +1,27 @@
+# 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.
+
+########################################################################
+# Install python sources
+########################################################################
+GR_PYTHON_INSTALL(
+ FILES
+ __init__.py
+ test_phasealignment.py DESTINATION ${GR_PYTHON_DIR}/usrptest/rts_tests
+)
diff --git a/tools/gr-usrptest/python/rts_tests/__init__.py b/tools/gr-usrptest/python/rts_tests/__init__.py
new file mode 100644
index 000000000..048e5638a
--- /dev/null
+++ b/tools/gr-usrptest/python/rts_tests/__init__.py
@@ -0,0 +1,14 @@
+"""
+usrptest.flowgraphs
+======================================
+
+Contents
+--------
+
+Subpackages
+-----------
+::
+
+The existance of the file turns the folder into a Python module.
+
+"""
diff --git a/tools/gr-usrptest/python/rts_tests/test_phasealignment.py b/tools/gr-usrptest/python/rts_tests/test_phasealignment.py
new file mode 100644
index 000000000..10642f298
--- /dev/null
+++ b/tools/gr-usrptest/python/rts_tests/test_phasealignment.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2016 Ettus Research LLC.
+#
+# This 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.
+#
+# This software 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 this software; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+import unittest
+from tinydb import TinyDB, Query
+from usrptest.flowgraphs import phasealignment_fg
+from usrptest.functions import setup_phase_alignment_parser, run_test
+from gnuradio.uhd.uhd_app import UHDApp
+import numpy as np
+import argparse
+import time
+
+class gr_usrp_test(unittest.TestCase):
+ def __init__(self, methodName='runTest', args=None):
+ super(gr_usrp_test,self).__init__(methodName)
+ self.args = args
+
+class qa_phasealignment(gr_usrp_test):
+ def setUp(self):
+ self.uhd_app = UHDApp(args=self.args)
+ self.tb = phasealignment_fg.phasealignment_fg(self.uhd_app)
+ self.db = TinyDB('phase_db.json')
+
+ def tearDown(self):
+ self.uhd_app = None
+ self.tb = None
+
+ def test_001(self):
+ self.tb.start()
+ time.sleep(2)
+ results = run_test(self.tb,self.args.runs) # dict key:dev, value: dict{dphase:[],stddev:[]}
+ time.sleep(1)
+ self.first_device = self.tb.measurement_channels_names[:-1]
+ self.second_device = self.tb.measurement_channels_names[1:]
+ #self.tb.stop()
+ #self.tb.wait()
+ self.time_stamp = time.strftime('%Y%m%d%H%M')
+ self.passed = True
+ for fdev, sdev in zip(self.first_device,self.second_device):
+ print('Comparing values for phase difference between {} and {}'.format(fdev, sdev))
+ dphase_list = results[fdev]['avg']
+ dev_list = results[fdev]['stddev']
+ dphase = np.average(dphase_list)
+ dev = np.average(dev_list)
+ ref_meas = get_reference_meas(self.db, fdev, sdev, self.args.freq)
+ for dphase_i in dphase_list:
+ passed = True
+ if abs(dphase_i - dphase) > self.args.dphi and passed:
+ print('\t dPhase of a measurement_run differs from average dhpase. dphase_run: {}, dphase_avg: {}'.format(dphase_i, dphase))
+ passed = False
+ if dev > self.args.phasedev:
+ print('\t dPhase deviates during measurement. stddev: {}'.format(dev))
+ passed = False
+ if ref_meas:
+ if abs(ref_meas['dphase'] - dphase) > self.args.dphi:
+ print('\t dPhase differs from reference measurement. Now: {}, reference: {}'.format(dphase, ref_meas['dphase']))
+ if not passed:
+ self.passed = False
+ else:
+ self.db.insert({'dev1':fdev, 'dev2':sdev, 'timestamp':self.time_stamp, 'dphase':dphase, 'dphase_dev': dev, 'freq': self.args.freq})
+ self.tb.stop()
+ self.assertTrue(self.passed)
+
+def get_previous_meas(db, dev1, dev2, freq):
+ meas = Query()
+ results = db.search((meas.dev1 == dev1) & (meas.dev2 == dev2) & (meas.freq == freq))
+ prev_result = dict()
+ if results:
+ prev_result = results[0]
+ for result in results:
+ if result['timestamp'] > prev_result['timestamp']:
+ prev_result = result
+ return prev_result
+
+def get_reference_meas(db, dev1, dev2, freq):
+ meas = Query()
+ results = db.search((meas.dev1 == dev1) & (meas.dev2 == dev2) & (meas.freq == freq))
+ ref_result = dict()
+ if results:
+ ref_result = results[0]
+ for result in results:
+ if result['timestamp'] < ref_result['timestamp']:
+ ref_result = result
+ return ref_result
+
+
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser(conflict_handler='resolve')
+ parser = setup_phase_alignment_parser(parser)
+ UHDApp.setup_argparser(parser=parser)
+ args = parser.parse_args()
+ def make_suite(testcase_class):
+ testloader = unittest.TestLoader()
+ testnames = testloader.getTestCaseNames(testcase_class)
+ suite = unittest.TestSuite()
+ for name in testnames:
+ suite.addTest(testcase_class(name, args=args))
+ return suite
+
+ # Add tests.
+ alltests = unittest.TestSuite()
+ alltests.addTest(make_suite(qa_phasealignment))
+ result = unittest.TextTestRunner(verbosity=2).run(alltests) # Run tests.