diff options
27 files changed, 4513 insertions, 3 deletions
diff --git a/tools/gr-usrptest/TODO b/tools/gr-usrptest/TODO new file mode 100644 index 000000000..0a56a49c3 --- /dev/null +++ b/tools/gr-usrptest/TODO @@ -0,0 +1,21 @@ + +- Measure & Report phase alignment and phase stability of USRPs + - Wire diagram:  + +    ______________       ______________  +   |              |     |              | +   |    USRP 1    |     |    USRP 2    | +   |______________|     |______________| +     ^ |______^ |_________^  |  +     |_______________________| + +    - USRP 1: send tone from first to second daughterboard - delta_phi_1 +    - USRP 1: send tone from second daughterboard to USPR 2 - delta_phi_2 +    - USRP 2: send tone to first daughterboard (USRP1) - delta_phi_3 +     +    Arbitrary number of RX-USRPs and TX-USRPs possible. + +    test_signal = sin(2*pi*f*t + phi) +    reference = sin(2*pi*f*t) + + diff --git a/tools/gr-usrptest/apps/CMakeLists.txt b/tools/gr-usrptest/apps/CMakeLists.txt index c837d77f6..a40192924 100644 --- a/tools/gr-usrptest/apps/CMakeLists.txt +++ b/tools/gr-usrptest/apps/CMakeLists.txt @@ -21,5 +21,6 @@ include(GrPython)  GR_PYTHON_INSTALL(      PROGRAMS +    usrp_phasealignment.py      DESTINATION bin  ) diff --git a/tools/gr-usrptest/apps/usrp_phasealignment.py b/tools/gr-usrptest/apps/usrp_phasealignment.py new file mode 100755 index 000000000..928788be4 --- /dev/null +++ b/tools/gr-usrptest/apps/usrp_phasealignment.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python + +from gnuradio.uhd.uhd_app import UHDApp +from usrptest.flowgraphs import phasealignment_fg +from usrptest.functions import run_test, setup_phase_alignment_parser, setup_tx_phase_alignment_parser, setup_manual_phase_alignment_parser +import time +import argparse + + +def plot_results(results): +    import matplotlib.pyplot as plt +    ax = plt.axes() +    ax.set_ylim(-180, 180) +    for result in results: +        plt.errorbar( +            range(len(result['avg'])), +            result["avg"], +            result["stddev"], +            label="{} - {}".format(result["first"], result["second"]), +            axes=ax) +    ax.legend(loc='upper left', bbox_to_anchor=(0.0, 0.0)) +    plt.show() + + +def print_results(results): +    for result in results: +        print('Results for: {first} - {second}'.format( +            first=result['first'], second=result['second'])) +        for i, (avg, +                stddev) in enumerate(zip(result['avg'], result['stddev'])): +            print('\t {}. run avg: {}, stddev: {}'.format(i + 1, avg, stddev)) + + +def main(): +    parser = argparse.ArgumentParser(conflict_handler='resolve') +    UHDApp.setup_argparser(parser=parser) +    parser = setup_phase_alignment_parser(parser) +    parser = setup_tx_phase_alignment_parser(parser) +    parser = setup_manual_phase_alignment_parser(parser) +    args = parser.parse_args() +    test_app = UHDApp(args=args) +    if args.auto and args.start_freq and args.stop_freq: +        from random import uniform +        bw = (args.stop_freq - args.start_freq) / args.freq_bands +        for nband in range(args.freq_bands): +            freq1 = args.start_freq + nband * bw +            new_freq = uniform(freq1, freq1 + bw) +            test_app.args.freq = new_freq +            raw_input( +                "New test frequency: {:f} MHz. Adjust your signal generator and press ENTER to start measurement.". +                format(new_freq / 1e6)) +            fg = phasealignment_fg.phasealignment_fg(test_app) +            fg.start() +            results = run_test(fg, args.runs) +            fg.stop() +            fg.wait() +            if args.plot: +                plot_results(results) +            print_results(results) +    else: +        fg = phasealignment_fg.phasealignment_fg(test_app) +        fg.start() +        results = run_test(fg, args.runs) +        fg.stop() +        fg.wait() +        if args.plot: +            plot_results(results) +        print_results(results) + + +if __name__ == '__main__': +    main() diff --git a/tools/gr-usrptest/apps/usrp_selftest.py b/tools/gr-usrptest/apps/usrp_selftest.py new file mode 100755 index 000000000..3dcd4e6ca --- /dev/null +++ b/tools/gr-usrptest/apps/usrp_selftest.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python + +import argparse +from usrptest import parsers +from usrptest.flowgraphs import selftest_fg + + +def main(): +    parser = argparse.ArgumentParser() +    parser = parsers.add_core_args(parser) +    parser = parsers.add_selftest_args(parser) +    args = parser.parse_args() +    my_flowgraph = selftest_fg.selftest_fg(args.frequency, args.samp_rate, args.dphase ,args.devices) +    results = my_flowgraph.run() +    print(results) +if __name__ == '__main__': +    main() diff --git a/tools/gr-usrptest/examples/phase_diff_x310_ubx_example.grc b/tools/gr-usrptest/examples/phase_diff_x310_ubx_example.grc new file mode 100644 index 000000000..f6cbe3d83 --- /dev/null +++ b/tools/gr-usrptest/examples/phase_diff_x310_ubx_example.grc @@ -0,0 +1,3296 @@ +<?xml version='1.0' encoding='utf-8'?> +<?grc format='1' created='3.7.11'?> +<flow_graph> +  <timestamp>Thu Oct  6 14:49:17 2016</timestamp> +  <block> +    <key>options</key> +    <param> +      <key>author</key> +      <value></value> +    </param> +    <param> +      <key>window_size</key> +      <value></value> +    </param> +    <param> +      <key>category</key> +      <value>[GRC Hier Blocks]</value> +    </param> +    <param> +      <key>comment</key> +      <value></value> +    </param> +    <param> +      <key>description</key> +      <value></value> +    </param> +    <param> +      <key>_enabled</key> +      <value>True</value> +    </param> +    <param> +      <key>_coordinate</key> +      <value>(8, 8)</value> +    </param> +    <param> +      <key>_rotation</key> +      <value>0</value> +    </param> +    <param> +      <key>generate_options</key> +      <value>qt_gui</value> +    </param> +    <param> +      <key>hier_block_src_path</key> +      <value>.:</value> +    </param> +    <param> +      <key>id</key> +      <value>phase_difference_x3x0_example</value> +    </param> +    <param> +      <key>max_nouts</key> +      <value>0</value> +    </param> +    <param> +      <key>qt_qss_theme</key> +      <value></value> +    </param> +    <param> +      <key>realtime_scheduling</key> +      <value></value> +    </param> +    <param> +      <key>run_command</key> +      <value>{python} -u {filename}</value> +    </param> +    <param> +      <key>run_options</key> +      <value>prompt</value> +    </param> +    <param> +      <key>run</key> +      <value>True</value> +    </param> +    <param> +      <key>thread_safe_setters</key> +      <value></value> +    </param> +    <param> +      <key>title</key> +      <value></value> +    </param> +  </block> +  <block> +    <key>variable</key> +    <param> +      <key>comment</key> +      <value></value> +    </param> +    <param> +      <key>_enabled</key> +      <value>0</value> +    </param> +    <param> +      <key>_coordinate</key> +      <value>(8, 100)</value> +    </param> +    <param> +      <key>_rotation</key> +      <value>0</value> +    </param> +    <param> +      <key>id</key> +      <value>baseband</value> +    </param> +    <param> +      <key>value</key> +      <value>3e9</value> +    </param> +  </block> +  <block> +    <key>variable_qtgui_range</key> +    <param> +      <key>comment</key> +      <value></value> +    </param> +    <param> +      <key>value</key> +      <value>10e6</value> +    </param> +    <param> +      <key>_enabled</key> +      <value>True</value> +    </param> +    <param> +      <key>_coordinate</key> +      <value>(200, 112)</value> +    </param> +    <param> +      <key>gui_hint</key> +      <value></value> +    </param> +    <param> +      <key>_rotation</key> +      <value>0</value> +    </param> +    <param> +      <key>id</key> +      <value>rx_base</value> +    </param> +    <param> +      <key>label</key> +      <value></value> +    </param> +    <param> +      <key>min_len</key> +      <value>200</value> +    </param> +    <param> +      <key>orient</key> +      <value>Qt.Horizontal</value> +    </param> +    <param> +      <key>start</key> +      <value>10e6</value> +    </param> +    <param> +      <key>step</key> +      <value>50e6</value> +    </param> +    <param> +      <key>stop</key> +      <value>6e9</value> +    </param> +    <param> +      <key>rangeType</key> +      <value>float</value> +    </param> +    <param> +      <key>widget</key> +      <value>counter_slider</value> +    </param> +  </block> +  <block> +    <key>variable</key> +    <param> +      <key>comment</key> +      <value></value> +    </param> +    <param> +      <key>_enabled</key> +      <value>True</value> +    </param> +    <param> +      <key>_coordinate</key> +      <value>(8, 160)</value> +    </param> +    <param> +      <key>_rotation</key> +      <value>0</value> +    </param> +    <param> +      <key>id</key> +      <value>samp_rate</value> +    </param> +    <param> +      <key>value</key> +      <value>10e6</value> +    </param> +  </block> +  <block> +    <key>variable_qtgui_range</key> +    <param> +      <key>comment</key> +      <value></value> +    </param> +    <param> +      <key>value</key> +      <value>10e6</value> +    </param> +    <param> +      <key>_enabled</key> +      <value>True</value> +    </param> +    <param> +      <key>_coordinate</key> +      <value>(168, 240)</value> +    </param> +    <param> +      <key>gui_hint</key> +      <value></value> +    </param> +    <param> +      <key>_rotation</key> +      <value>0</value> +    </param> +    <param> +      <key>id</key> +      <value>tx_base</value> +    </param> +    <param> +      <key>label</key> +      <value></value> +    </param> +    <param> +      <key>min_len</key> +      <value>200</value> +    </param> +    <param> +      <key>orient</key> +      <value>Qt.Horizontal</value> +    </param> +    <param> +      <key>start</key> +      <value>10e6</value> +    </param> +    <param> +      <key>step</key> +      <value>50e6</value> +    </param> +    <param> +      <key>stop</key> +      <value>6e9</value> +    </param> +    <param> +      <key>rangeType</key> +      <value>float</value> +    </param> +    <param> +      <key>widget</key> +      <value>counter_slider</value> +    </param> +  </block> +  <block> +    <key>analog_sig_source_x</key> +    <param> +      <key>amp</key> +      <value>1</value> +    </param> +    <param> +      <key>alias</key> +      <value></value> +    </param> +    <param> +      <key>comment</key> +      <value></value> +    </param> +    <param> +      <key>affinity</key> +      <value></value> +    </param> +    <param> +      <key>_enabled</key> +      <value>1</value> +    </param> +    <param> +      <key>freq</key> +      <value>100e3</value> +    </param> +    <param> +      <key>_coordinate</key> +      <value>(440, 112)</value> +    </param> +    <param> +      <key>_rotation</key> +      <value>0</value> +    </param> +    <param> +      <key>id</key> +      <value>analog_sig_source_x_1</value> +    </param> +    <param> +      <key>maxoutbuf</key> +      <value>0</value> +    </param> +    <param> +      <key>minoutbuf</key> +      <value>0</value> +    </param> +    <param> +      <key>offset</key> +      <value>0</value> +    </param> +    <param> +      <key>type</key> +      <value>complex</value> +    </param> +    <param> +      <key>samp_rate</key> +      <value>samp_rate</value> +    </param> +    <param> +      <key>waveform</key> +      <value>analog.GR_COS_WAVE</value> +    </param> +  </block> +  <block> +    <key>qtgui_time_sink_x</key> +    <param> +      <key>autoscale</key> +      <value>False</value> +    </param> +    <param> +      <key>axislabels</key> +      <value>True</value> +    </param> +    <param> +      <key>alias</key> +      <value></value> +    </param> +    <param> +      <key>comment</key> +      <value></value> +    </param> +    <param> +      <key>ctrlpanel</key> +      <value>False</value> +    </param> +    <param> +      <key>affinity</key> +      <value></value> +    </param> +    <param> +      <key>entags</key> +      <value>True</value> +    </param> +    <param> +      <key>_enabled</key> +      <value>True</value> +    </param> +    <param> +      <key>_coordinate</key> +      <value>(768, 404)</value> +    </param> +    <param> +      <key>gui_hint</key> +      <value></value> +    </param> +    <param> +      <key>_rotation</key> +      <value>0</value> +    </param> +    <param> +      <key>grid</key> +      <value>False</value> +    </param> +    <param> +      <key>id</key> +      <value>qtgui_time_sink_x_0</value> +    </param> +    <param> +      <key>legend</key> +      <value>True</value> +    </param> +    <param> +      <key>alpha1</key> +      <value>1.0</value> +    </param> +    <param> +      <key>color1</key> +      <value>"blue"</value> +    </param> +    <param> +      <key>label1</key> +      <value></value> +    </param> +    <param> +      <key>marker1</key> +      <value>-1</value> +    </param> +    <param> +      <key>style1</key> +      <value>1</value> +    </param> +    <param> +      <key>width1</key> +      <value>1</value> +    </param> +    <param> +      <key>alpha10</key> +      <value>1.0</value> +    </param> +    <param> +      <key>color10</key> +      <value>"blue"</value> +    </param> +    <param> +      <key>label10</key> +      <value></value> +    </param> +    <param> +      <key>marker10</key> +      <value>-1</value> +    </param> +    <param> +      <key>style10</key> +      <value>1</value> +    </param> +    <param> +      <key>width10</key> +      <value>1</value> +    </param> +    <param> +      <key>alpha2</key> +      <value>1.0</value> +    </param> +    <param> +      <key>color2</key> +      <value>"red"</value> +    </param> +    <param> +      <key>label2</key> +      <value></value> +    </param> +    <param> +      <key>marker2</key> +      <value>-1</value> +    </param> +    <param> +      <key>style2</key> +      <value>1</value> +    </param> +    <param> +      <key>width2</key> +      <value>1</value> +    </param> +    <param> +      <key>alpha3</key> +      <value>1.0</value> +    </param> +    <param> +      <key>color3</key> +      <value>"green"</value> +    </param> +    <param> +      <key>label3</key> +      <value></value> +    </param> +    <param> +      <key>marker3</key> +      <value>-1</value> +    </param> +    <param> +      <key>style3</key> +      <value>1</value> +    </param> +    <param> +      <key>width3</key> +      <value>1</value> +    </param> +    <param> +      <key>alpha4</key> +      <value>1.0</value> +    </param> +    <param> +      <key>color4</key> +      <value>"black"</value> +    </param> +    <param> +      <key>label4</key> +      <value></value> +    </param> +    <param> +      <key>marker4</key> +      <value>-1</value> +    </param> +    <param> +      <key>style4</key> +      <value>1</value> +    </param> +    <param> +      <key>width4</key> +      <value>1</value> +    </param> +    <param> +      <key>alpha5</key> +      <value>1.0</value> +    </param> +    <param> +      <key>color5</key> +      <value>"cyan"</value> +    </param> +    <param> +      <key>label5</key> +      <value></value> +    </param> +    <param> +      <key>marker5</key> +      <value>-1</value> +    </param> +    <param> +      <key>style5</key> +      <value>1</value> +    </param> +    <param> +      <key>width5</key> +      <value>1</value> +    </param> +    <param> +      <key>alpha6</key> +      <value>1.0</value> +    </param> +    <param> +      <key>color6</key> +      <value>"magenta"</value> +    </param> +    <param> +      <key>label6</key> +      <value></value> +    </param> +    <param> +      <key>marker6</key> +      <value>-1</value> +    </param> +    <param> +      <key>style6</key> +      <value>1</value> +    </param> +    <param> +      <key>width6</key> +      <value>1</value> +    </param> +    <param> +      <key>alpha7</key> +      <value>1.0</value> +    </param> +    <param> +      <key>color7</key> +      <value>"yellow"</value> +    </param> +    <param> +      <key>label7</key> +      <value></value> +    </param> +    <param> +      <key>marker7</key> +      <value>-1</value> +    </param> +    <param> +      <key>style7</key> +      <value>1</value> +    </param> +    <param> +      <key>width7</key> +      <value>1</value> +    </param> +    <param> +      <key>alpha8</key> +      <value>1.0</value> +    </param> +    <param> +      <key>color8</key> +      <value>"dark red"</value> +    </param> +    <param> +      <key>label8</key> +      <value></value> +    </param> +    <param> +      <key>marker8</key> +      <value>-1</value> +    </param> +    <param> +      <key>style8</key> +      <value>1</value> +    </param> +    <param> +      <key>width8</key> +      <value>1</value> +    </param> +    <param> +      <key>alpha9</key> +      <value>1.0</value> +    </param> +    <param> +      <key>color9</key> +      <value>"dark green"</value> +    </param> +    <param> +      <key>label9</key> +      <value></value> +    </param> +    <param> +      <key>marker9</key> +      <value>-1</value> +    </param> +    <param> +      <key>style9</key> +      <value>1</value> +    </param> +    <param> +      <key>width9</key> +      <value>1</value> +    </param> +    <param> +      <key>name</key> +      <value>""</value> +    </param> +    <param> +      <key>nconnections</key> +      <value>1</value> +    </param> +    <param> +      <key>size</key> +      <value>1024</value> +    </param> +    <param> +      <key>srate</key> +      <value>samp_rate</value> +    </param> +    <param> +      <key>tr_chan</key> +      <value>0</value> +    </param> +    <param> +      <key>tr_delay</key> +      <value>0</value> +    </param> +    <param> +      <key>tr_level</key> +      <value>0.0</value> +    </param> +    <param> +      <key>tr_mode</key> +      <value>qtgui.TRIG_MODE_FREE</value> +    </param> +    <param> +      <key>tr_slope</key> +      <value>qtgui.TRIG_SLOPE_POS</value> +    </param> +    <param> +      <key>tr_tag</key> +      <value>""</value> +    </param> +    <param> +      <key>type</key> +      <value>float</value> +    </param> +    <param> +      <key>update_time</key> +      <value>0.10</value> +    </param> +    <param> +      <key>ylabel</key> +      <value>Amplitude</value> +    </param> +    <param> +      <key>yunit</key> +      <value>""</value> +    </param> +    <param> +      <key>ymax</key> +      <value>1</value> +    </param> +    <param> +      <key>ymin</key> +      <value>-1</value> +    </param> +  </block> +  <block> +    <key>qtgui_time_sink_x</key> +    <param> +      <key>autoscale</key> +      <value>False</value> +    </param> +    <param> +      <key>axislabels</key> +      <value>True</value> +    </param> +    <param> +      <key>alias</key> +      <value></value> +    </param> +    <param> +      <key>comment</key> +      <value></value> +    </param> +    <param> +      <key>ctrlpanel</key> +      <value>False</value> +    </param> +    <param> +      <key>affinity</key> +      <value></value> +    </param> +    <param> +      <key>entags</key> +      <value>True</value> +    </param> +    <param> +      <key>_enabled</key> +      <value>0</value> +    </param> +    <param> +      <key>_coordinate</key> +      <value>(664, 280)</value> +    </param> +    <param> +      <key>gui_hint</key> +      <value></value> +    </param> +    <param> +      <key>_rotation</key> +      <value>0</value> +    </param> +    <param> +      <key>grid</key> +      <value>False</value> +    </param> +    <param> +      <key>id</key> +      <value>qtgui_time_sink_x_1</value> +    </param> +    <param> +      <key>legend</key> +      <value>True</value> +    </param> +    <param> +      <key>alpha1</key> +      <value>1.0</value> +    </param> +    <param> +      <key>color1</key> +      <value>"blue"</value> +    </param> +    <param> +      <key>label1</key> +      <value></value> +    </param> +    <param> +      <key>marker1</key> +      <value>-1</value> +    </param> +    <param> +      <key>style1</key> +      <value>1</value> +    </param> +    <param> +      <key>width1</key> +      <value>1</value> +    </param> +    <param> +      <key>alpha10</key> +      <value>1.0</value> +    </param> +    <param> +      <key>color10</key> +      <value>"blue"</value> +    </param> +    <param> +      <key>label10</key> +      <value></value> +    </param> +    <param> +      <key>marker10</key> +      <value>-1</value> +    </param> +    <param> +      <key>style10</key> +      <value>1</value> +    </param> +    <param> +      <key>width10</key> +      <value>1</value> +    </param> +    <param> +      <key>alpha2</key> +      <value>1.0</value> +    </param> +    <param> +      <key>color2</key> +      <value>"red"</value> +    </param> +    <param> +      <key>label2</key> +      <value></value> +    </param> +    <param> +      <key>marker2</key> +      <value>-1</value> +    </param> +    <param> +      <key>style2</key> +      <value>1</value> +    </param> +    <param> +      <key>width2</key> +      <value>1</value> +    </param> +    <param> +      <key>alpha3</key> +      <value>1.0</value> +    </param> +    <param> +      <key>color3</key> +      <value>"green"</value> +    </param> +    <param> +      <key>label3</key> +      <value></value> +    </param> +    <param> +      <key>marker3</key> +      <value>-1</value> +    </param> +    <param> +      <key>style3</key> +      <value>1</value> +    </param> +    <param> +      <key>width3</key> +      <value>1</value> +    </param> +    <param> +      <key>alpha4</key> +      <value>1.0</value> +    </param> +    <param> +      <key>color4</key> +      <value>"black"</value> +    </param> +    <param> +      <key>label4</key> +      <value></value> +    </param> +    <param> +      <key>marker4</key> +      <value>-1</value> +    </param> +    <param> +      <key>style4</key> +      <value>1</value> +    </param> +    <param> +      <key>width4</key> +      <value>1</value> +    </param> +    <param> +      <key>alpha5</key> +      <value>1.0</value> +    </param> +    <param> +      <key>color5</key> +      <value>"cyan"</value> +    </param> +    <param> +      <key>label5</key> +      <value></value> +    </param> +    <param> +      <key>marker5</key> +      <value>-1</value> +    </param> +    <param> +      <key>style5</key> +      <value>1</value> +    </param> +    <param> +      <key>width5</key> +      <value>1</value> +    </param> +    <param> +      <key>alpha6</key> +      <value>1.0</value> +    </param> +    <param> +      <key>color6</key> +      <value>"magenta"</value> +    </param> +    <param> +      <key>label6</key> +      <value></value> +    </param> +    <param> +      <key>marker6</key> +      <value>-1</value> +    </param> +    <param> +      <key>style6</key> +      <value>1</value> +    </param> +    <param> +      <key>width6</key> +      <value>1</value> +    </param> +    <param> +      <key>alpha7</key> +      <value>1.0</value> +    </param> +    <param> +      <key>color7</key> +      <value>"yellow"</value> +    </param> +    <param> +      <key>label7</key> +      <value></value> +    </param> +    <param> +      <key>marker7</key> +      <value>-1</value> +    </param> +    <param> +      <key>style7</key> +      <value>1</value> +    </param> +    <param> +      <key>width7</key> +      <value>1</value> +    </param> +    <param> +      <key>alpha8</key> +      <value>1.0</value> +    </param> +    <param> +      <key>color8</key> +      <value>"dark red"</value> +    </param> +    <param> +      <key>label8</key> +      <value></value> +    </param> +    <param> +      <key>marker8</key> +      <value>-1</value> +    </param> +    <param> +      <key>style8</key> +      <value>1</value> +    </param> +    <param> +      <key>width8</key> +      <value>1</value> +    </param> +    <param> +      <key>alpha9</key> +      <value>1.0</value> +    </param> +    <param> +      <key>color9</key> +      <value>"dark green"</value> +    </param> +    <param> +      <key>label9</key> +      <value></value> +    </param> +    <param> +      <key>marker9</key> +      <value>-1</value> +    </param> +    <param> +      <key>style9</key> +      <value>1</value> +    </param> +    <param> +      <key>width9</key> +      <value>1</value> +    </param> +    <param> +      <key>name</key> +      <value>""</value> +    </param> +    <param> +      <key>nconnections</key> +      <value>2</value> +    </param> +    <param> +      <key>size</key> +      <value>1024</value> +    </param> +    <param> +      <key>srate</key> +      <value>samp_rate</value> +    </param> +    <param> +      <key>tr_chan</key> +      <value>0</value> +    </param> +    <param> +      <key>tr_delay</key> +      <value>0</value> +    </param> +    <param> +      <key>tr_level</key> +      <value>0.0</value> +    </param> +    <param> +      <key>tr_mode</key> +      <value>qtgui.TRIG_MODE_FREE</value> +    </param> +    <param> +      <key>tr_slope</key> +      <value>qtgui.TRIG_SLOPE_POS</value> +    </param> +    <param> +      <key>tr_tag</key> +      <value>""</value> +    </param> +    <param> +      <key>type</key> +      <value>complex</value> +    </param> +    <param> +      <key>update_time</key> +      <value>0.10</value> +    </param> +    <param> +      <key>ylabel</key> +      <value>Amplitude</value> +    </param> +    <param> +      <key>yunit</key> +      <value>""</value> +    </param> +    <param> +      <key>ymax</key> +      <value>1</value> +    </param> +    <param> +      <key>ymin</key> +      <value>-1</value> +    </param> +  </block> +  <block> +    <key>uhd_usrp_sink</key> +    <param> +      <key>alias</key> +      <value></value> +    </param> +    <param> +      <key>ant0</key> +      <value></value> +    </param> +    <param> +      <key>bw0</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq0</key> +      <value>tx_base</value> +    </param> +    <param> +      <key>norm_gain0</key> +      <value>False</value> +    </param> +    <param> +      <key>gain0</key> +      <value>15</value> +    </param> +    <param> +      <key>ant10</key> +      <value></value> +    </param> +    <param> +      <key>bw10</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq10</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain10</key> +      <value>False</value> +    </param> +    <param> +      <key>gain10</key> +      <value>0</value> +    </param> +    <param> +      <key>ant11</key> +      <value></value> +    </param> +    <param> +      <key>bw11</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq11</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain11</key> +      <value>False</value> +    </param> +    <param> +      <key>gain11</key> +      <value>0</value> +    </param> +    <param> +      <key>ant12</key> +      <value></value> +    </param> +    <param> +      <key>bw12</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq12</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain12</key> +      <value>False</value> +    </param> +    <param> +      <key>gain12</key> +      <value>0</value> +    </param> +    <param> +      <key>ant13</key> +      <value></value> +    </param> +    <param> +      <key>bw13</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq13</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain13</key> +      <value>False</value> +    </param> +    <param> +      <key>gain13</key> +      <value>0</value> +    </param> +    <param> +      <key>ant14</key> +      <value></value> +    </param> +    <param> +      <key>bw14</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq14</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain14</key> +      <value>False</value> +    </param> +    <param> +      <key>gain14</key> +      <value>0</value> +    </param> +    <param> +      <key>ant15</key> +      <value></value> +    </param> +    <param> +      <key>bw15</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq15</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain15</key> +      <value>False</value> +    </param> +    <param> +      <key>gain15</key> +      <value>0</value> +    </param> +    <param> +      <key>ant16</key> +      <value></value> +    </param> +    <param> +      <key>bw16</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq16</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain16</key> +      <value>False</value> +    </param> +    <param> +      <key>gain16</key> +      <value>0</value> +    </param> +    <param> +      <key>ant17</key> +      <value></value> +    </param> +    <param> +      <key>bw17</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq17</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain17</key> +      <value>False</value> +    </param> +    <param> +      <key>gain17</key> +      <value>0</value> +    </param> +    <param> +      <key>ant18</key> +      <value></value> +    </param> +    <param> +      <key>bw18</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq18</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain18</key> +      <value>False</value> +    </param> +    <param> +      <key>gain18</key> +      <value>0</value> +    </param> +    <param> +      <key>ant19</key> +      <value></value> +    </param> +    <param> +      <key>bw19</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq19</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain19</key> +      <value>False</value> +    </param> +    <param> +      <key>gain19</key> +      <value>0</value> +    </param> +    <param> +      <key>ant1</key> +      <value></value> +    </param> +    <param> +      <key>bw1</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq1</key> +      <value>tx_base</value> +    </param> +    <param> +      <key>norm_gain1</key> +      <value>False</value> +    </param> +    <param> +      <key>gain1</key> +      <value>15</value> +    </param> +    <param> +      <key>ant20</key> +      <value></value> +    </param> +    <param> +      <key>bw20</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq20</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain20</key> +      <value>False</value> +    </param> +    <param> +      <key>gain20</key> +      <value>0</value> +    </param> +    <param> +      <key>ant21</key> +      <value></value> +    </param> +    <param> +      <key>bw21</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq21</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain21</key> +      <value>False</value> +    </param> +    <param> +      <key>gain21</key> +      <value>0</value> +    </param> +    <param> +      <key>ant22</key> +      <value></value> +    </param> +    <param> +      <key>bw22</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq22</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain22</key> +      <value>False</value> +    </param> +    <param> +      <key>gain22</key> +      <value>0</value> +    </param> +    <param> +      <key>ant23</key> +      <value></value> +    </param> +    <param> +      <key>bw23</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq23</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain23</key> +      <value>False</value> +    </param> +    <param> +      <key>gain23</key> +      <value>0</value> +    </param> +    <param> +      <key>ant24</key> +      <value></value> +    </param> +    <param> +      <key>bw24</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq24</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain24</key> +      <value>False</value> +    </param> +    <param> +      <key>gain24</key> +      <value>0</value> +    </param> +    <param> +      <key>ant25</key> +      <value></value> +    </param> +    <param> +      <key>bw25</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq25</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain25</key> +      <value>False</value> +    </param> +    <param> +      <key>gain25</key> +      <value>0</value> +    </param> +    <param> +      <key>ant26</key> +      <value></value> +    </param> +    <param> +      <key>bw26</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq26</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain26</key> +      <value>False</value> +    </param> +    <param> +      <key>gain26</key> +      <value>0</value> +    </param> +    <param> +      <key>ant27</key> +      <value></value> +    </param> +    <param> +      <key>bw27</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq27</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain27</key> +      <value>False</value> +    </param> +    <param> +      <key>gain27</key> +      <value>0</value> +    </param> +    <param> +      <key>ant28</key> +      <value></value> +    </param> +    <param> +      <key>bw28</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq28</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain28</key> +      <value>False</value> +    </param> +    <param> +      <key>gain28</key> +      <value>0</value> +    </param> +    <param> +      <key>ant29</key> +      <value></value> +    </param> +    <param> +      <key>bw29</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq29</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain29</key> +      <value>False</value> +    </param> +    <param> +      <key>gain29</key> +      <value>0</value> +    </param> +    <param> +      <key>ant2</key> +      <value></value> +    </param> +    <param> +      <key>bw2</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq2</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain2</key> +      <value>False</value> +    </param> +    <param> +      <key>gain2</key> +      <value>0</value> +    </param> +    <param> +      <key>ant30</key> +      <value></value> +    </param> +    <param> +      <key>bw30</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq30</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain30</key> +      <value>False</value> +    </param> +    <param> +      <key>gain30</key> +      <value>0</value> +    </param> +    <param> +      <key>ant31</key> +      <value></value> +    </param> +    <param> +      <key>bw31</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq31</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain31</key> +      <value>False</value> +    </param> +    <param> +      <key>gain31</key> +      <value>0</value> +    </param> +    <param> +      <key>ant3</key> +      <value></value> +    </param> +    <param> +      <key>bw3</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq3</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain3</key> +      <value>False</value> +    </param> +    <param> +      <key>gain3</key> +      <value>0</value> +    </param> +    <param> +      <key>ant4</key> +      <value></value> +    </param> +    <param> +      <key>bw4</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq4</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain4</key> +      <value>False</value> +    </param> +    <param> +      <key>gain4</key> +      <value>0</value> +    </param> +    <param> +      <key>ant5</key> +      <value></value> +    </param> +    <param> +      <key>bw5</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq5</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain5</key> +      <value>False</value> +    </param> +    <param> +      <key>gain5</key> +      <value>0</value> +    </param> +    <param> +      <key>ant6</key> +      <value></value> +    </param> +    <param> +      <key>bw6</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq6</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain6</key> +      <value>False</value> +    </param> +    <param> +      <key>gain6</key> +      <value>0</value> +    </param> +    <param> +      <key>ant7</key> +      <value></value> +    </param> +    <param> +      <key>bw7</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq7</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain7</key> +      <value>False</value> +    </param> +    <param> +      <key>gain7</key> +      <value>0</value> +    </param> +    <param> +      <key>ant8</key> +      <value></value> +    </param> +    <param> +      <key>bw8</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq8</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain8</key> +      <value>False</value> +    </param> +    <param> +      <key>gain8</key> +      <value>0</value> +    </param> +    <param> +      <key>ant9</key> +      <value></value> +    </param> +    <param> +      <key>bw9</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq9</key> +      <value>0</value> +    </param> +    <param> +      <key>norm_gain9</key> +      <value>False</value> +    </param> +    <param> +      <key>gain9</key> +      <value>0</value> +    </param> +    <param> +      <key>clock_rate</key> +      <value>0.0</value> +    </param> +    <param> +      <key>comment</key> +      <value></value> +    </param> +    <param> +      <key>affinity</key> +      <value></value> +    </param> +    <param> +      <key>dev_addr</key> +      <value>"addr=192.168.10.2"</value> +    </param> +    <param> +      <key>dev_args</key> +      <value>""</value> +    </param> +    <param> +      <key>_enabled</key> +      <value>1</value> +    </param> +    <param> +      <key>_coordinate</key> +      <value>(816, 104)</value> +    </param> +    <param> +      <key>_rotation</key> +      <value>0</value> +    </param> +    <param> +      <key>id</key> +      <value>uhd_usrp_sink_1</value> +    </param> +    <param> +      <key>type</key> +      <value>fc32</value> +    </param> +    <param> +      <key>clock_source0</key> +      <value></value> +    </param> +    <param> +      <key>sd_spec0</key> +      <value>"A:0 B:0"</value> +    </param> +    <param> +      <key>time_source0</key> +      <value></value> +    </param> +    <param> +      <key>clock_source1</key> +      <value></value> +    </param> +    <param> +      <key>sd_spec1</key> +      <value></value> +    </param> +    <param> +      <key>time_source1</key> +      <value></value> +    </param> +    <param> +      <key>clock_source2</key> +      <value></value> +    </param> +    <param> +      <key>sd_spec2</key> +      <value></value> +    </param> +    <param> +      <key>time_source2</key> +      <value></value> +    </param> +    <param> +      <key>clock_source3</key> +      <value></value> +    </param> +    <param> +      <key>sd_spec3</key> +      <value></value> +    </param> +    <param> +      <key>time_source3</key> +      <value></value> +    </param> +    <param> +      <key>clock_source4</key> +      <value></value> +    </param> +    <param> +      <key>sd_spec4</key> +      <value></value> +    </param> +    <param> +      <key>time_source4</key> +      <value></value> +    </param> +    <param> +      <key>clock_source5</key> +      <value></value> +    </param> +    <param> +      <key>sd_spec5</key> +      <value></value> +    </param> +    <param> +      <key>time_source5</key> +      <value></value> +    </param> +    <param> +      <key>clock_source6</key> +      <value></value> +    </param> +    <param> +      <key>sd_spec6</key> +      <value></value> +    </param> +    <param> +      <key>time_source6</key> +      <value></value> +    </param> +    <param> +      <key>clock_source7</key> +      <value></value> +    </param> +    <param> +      <key>sd_spec7</key> +      <value></value> +    </param> +    <param> +      <key>time_source7</key> +      <value></value> +    </param> +    <param> +      <key>nchan</key> +      <value>2</value> +    </param> +    <param> +      <key>num_mboards</key> +      <value>1</value> +    </param> +    <param> +      <key>samp_rate</key> +      <value>samp_rate</value> +    </param> +    <param> +      <key>hide_cmd_port</key> +      <value>False</value> +    </param> +    <param> +      <key>hide_lo_controls</key> +      <value>True</value> +    </param> +    <param> +      <key>stream_args</key> +      <value></value> +    </param> +    <param> +      <key>stream_chans</key> +      <value>[]</value> +    </param> +    <param> +      <key>sync</key> +      <value></value> +    </param> +    <param> +      <key>len_tag_name</key> +      <value></value> +    </param> +    <param> +      <key>otw</key> +      <value></value> +    </param> +  </block> +  <block> +    <key>uhd_usrp_source</key> +    <param> +      <key>alias</key> +      <value></value> +    </param> +    <param> +      <key>ant0</key> +      <value></value> +    </param> +    <param> +      <key>bw0</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq0</key> +      <value>rx_base</value> +    </param> +    <param> +      <key>dc_offs_enb0</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb0</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain0</key> +      <value>False</value> +    </param> +    <param> +      <key>gain0</key> +      <value>15</value> +    </param> +    <param> +      <key>lo_export0</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source0</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant10</key> +      <value></value> +    </param> +    <param> +      <key>bw10</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq10</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb10</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb10</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain10</key> +      <value>False</value> +    </param> +    <param> +      <key>gain10</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export10</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source10</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant11</key> +      <value></value> +    </param> +    <param> +      <key>bw11</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq11</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb11</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb11</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain11</key> +      <value>False</value> +    </param> +    <param> +      <key>gain11</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export11</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source11</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant12</key> +      <value></value> +    </param> +    <param> +      <key>bw12</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq12</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb12</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb12</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain12</key> +      <value>False</value> +    </param> +    <param> +      <key>gain12</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export12</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source12</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant13</key> +      <value></value> +    </param> +    <param> +      <key>bw13</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq13</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb13</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb13</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain13</key> +      <value>False</value> +    </param> +    <param> +      <key>gain13</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export13</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source13</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant14</key> +      <value></value> +    </param> +    <param> +      <key>bw14</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq14</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb14</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb14</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain14</key> +      <value>False</value> +    </param> +    <param> +      <key>gain14</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export14</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source14</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant15</key> +      <value></value> +    </param> +    <param> +      <key>bw15</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq15</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb15</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb15</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain15</key> +      <value>False</value> +    </param> +    <param> +      <key>gain15</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export15</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source15</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant16</key> +      <value></value> +    </param> +    <param> +      <key>bw16</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq16</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb16</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb16</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain16</key> +      <value>False</value> +    </param> +    <param> +      <key>gain16</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export16</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source16</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant17</key> +      <value></value> +    </param> +    <param> +      <key>bw17</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq17</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb17</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb17</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain17</key> +      <value>False</value> +    </param> +    <param> +      <key>gain17</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export17</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source17</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant18</key> +      <value></value> +    </param> +    <param> +      <key>bw18</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq18</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb18</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb18</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain18</key> +      <value>False</value> +    </param> +    <param> +      <key>gain18</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export18</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source18</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant19</key> +      <value></value> +    </param> +    <param> +      <key>bw19</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq19</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb19</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb19</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain19</key> +      <value>False</value> +    </param> +    <param> +      <key>gain19</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export19</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source19</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant1</key> +      <value></value> +    </param> +    <param> +      <key>bw1</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq1</key> +      <value>rx_base</value> +    </param> +    <param> +      <key>dc_offs_enb1</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb1</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain1</key> +      <value>False</value> +    </param> +    <param> +      <key>gain1</key> +      <value>15</value> +    </param> +    <param> +      <key>lo_export1</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source1</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant20</key> +      <value></value> +    </param> +    <param> +      <key>bw20</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq20</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb20</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb20</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain20</key> +      <value>False</value> +    </param> +    <param> +      <key>gain20</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export20</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source20</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant21</key> +      <value></value> +    </param> +    <param> +      <key>bw21</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq21</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb21</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb21</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain21</key> +      <value>False</value> +    </param> +    <param> +      <key>gain21</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export21</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source21</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant22</key> +      <value></value> +    </param> +    <param> +      <key>bw22</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq22</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb22</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb22</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain22</key> +      <value>False</value> +    </param> +    <param> +      <key>gain22</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export22</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source22</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant23</key> +      <value></value> +    </param> +    <param> +      <key>bw23</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq23</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb23</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb23</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain23</key> +      <value>False</value> +    </param> +    <param> +      <key>gain23</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export23</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source23</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant24</key> +      <value></value> +    </param> +    <param> +      <key>bw24</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq24</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb24</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb24</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain24</key> +      <value>False</value> +    </param> +    <param> +      <key>gain24</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export24</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source24</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant25</key> +      <value></value> +    </param> +    <param> +      <key>bw25</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq25</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb25</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb25</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain25</key> +      <value>False</value> +    </param> +    <param> +      <key>gain25</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export25</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source25</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant26</key> +      <value></value> +    </param> +    <param> +      <key>bw26</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq26</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb26</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb26</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain26</key> +      <value>False</value> +    </param> +    <param> +      <key>gain26</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export26</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source26</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant27</key> +      <value></value> +    </param> +    <param> +      <key>bw27</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq27</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb27</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb27</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain27</key> +      <value>False</value> +    </param> +    <param> +      <key>gain27</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export27</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source27</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant28</key> +      <value></value> +    </param> +    <param> +      <key>bw28</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq28</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb28</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb28</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain28</key> +      <value>False</value> +    </param> +    <param> +      <key>gain28</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export28</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source28</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant29</key> +      <value></value> +    </param> +    <param> +      <key>bw29</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq29</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb29</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb29</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain29</key> +      <value>False</value> +    </param> +    <param> +      <key>gain29</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export29</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source29</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant2</key> +      <value></value> +    </param> +    <param> +      <key>bw2</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq2</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb2</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb2</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain2</key> +      <value>False</value> +    </param> +    <param> +      <key>gain2</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export2</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source2</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant30</key> +      <value></value> +    </param> +    <param> +      <key>bw30</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq30</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb30</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb30</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain30</key> +      <value>False</value> +    </param> +    <param> +      <key>gain30</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export30</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source30</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant31</key> +      <value></value> +    </param> +    <param> +      <key>bw31</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq31</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb31</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb31</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain31</key> +      <value>False</value> +    </param> +    <param> +      <key>gain31</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export31</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source31</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant3</key> +      <value></value> +    </param> +    <param> +      <key>bw3</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq3</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb3</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb3</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain3</key> +      <value>False</value> +    </param> +    <param> +      <key>gain3</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export3</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source3</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant4</key> +      <value></value> +    </param> +    <param> +      <key>bw4</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq4</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb4</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb4</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain4</key> +      <value>False</value> +    </param> +    <param> +      <key>gain4</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export4</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source4</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant5</key> +      <value></value> +    </param> +    <param> +      <key>bw5</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq5</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb5</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb5</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain5</key> +      <value>False</value> +    </param> +    <param> +      <key>gain5</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export5</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source5</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant6</key> +      <value></value> +    </param> +    <param> +      <key>bw6</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq6</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb6</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb6</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain6</key> +      <value>False</value> +    </param> +    <param> +      <key>gain6</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export6</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source6</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant7</key> +      <value></value> +    </param> +    <param> +      <key>bw7</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq7</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb7</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb7</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain7</key> +      <value>False</value> +    </param> +    <param> +      <key>gain7</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export7</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source7</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant8</key> +      <value></value> +    </param> +    <param> +      <key>bw8</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq8</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb8</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb8</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain8</key> +      <value>False</value> +    </param> +    <param> +      <key>gain8</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export8</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source8</key> +      <value>internal</value> +    </param> +    <param> +      <key>ant9</key> +      <value></value> +    </param> +    <param> +      <key>bw9</key> +      <value>0</value> +    </param> +    <param> +      <key>center_freq9</key> +      <value>0</value> +    </param> +    <param> +      <key>dc_offs_enb9</key> +      <value>""</value> +    </param> +    <param> +      <key>iq_imbal_enb9</key> +      <value>""</value> +    </param> +    <param> +      <key>norm_gain9</key> +      <value>False</value> +    </param> +    <param> +      <key>gain9</key> +      <value>0</value> +    </param> +    <param> +      <key>lo_export9</key> +      <value>False</value> +    </param> +    <param> +      <key>lo_source9</key> +      <value>internal</value> +    </param> +    <param> +      <key>clock_rate</key> +      <value>0.0</value> +    </param> +    <param> +      <key>comment</key> +      <value></value> +    </param> +    <param> +      <key>affinity</key> +      <value></value> +    </param> +    <param> +      <key>dev_addr</key> +      <value>"addr=192.168.10.2"</value> +    </param> +    <param> +      <key>dev_args</key> +      <value>""</value> +    </param> +    <param> +      <key>_enabled</key> +      <value>True</value> +    </param> +    <param> +      <key>_coordinate</key> +      <value>(320, 376)</value> +    </param> +    <param> +      <key>_rotation</key> +      <value>0</value> +    </param> +    <param> +      <key>id</key> +      <value>uhd_usrp_source_0</value> +    </param> +    <param> +      <key>maxoutbuf</key> +      <value>0</value> +    </param> +    <param> +      <key>clock_source0</key> +      <value></value> +    </param> +    <param> +      <key>sd_spec0</key> +      <value>"A:0 B:0"</value> +    </param> +    <param> +      <key>time_source0</key> +      <value></value> +    </param> +    <param> +      <key>clock_source1</key> +      <value></value> +    </param> +    <param> +      <key>sd_spec1</key> +      <value></value> +    </param> +    <param> +      <key>time_source1</key> +      <value></value> +    </param> +    <param> +      <key>clock_source2</key> +      <value></value> +    </param> +    <param> +      <key>sd_spec2</key> +      <value></value> +    </param> +    <param> +      <key>time_source2</key> +      <value></value> +    </param> +    <param> +      <key>clock_source3</key> +      <value></value> +    </param> +    <param> +      <key>sd_spec3</key> +      <value></value> +    </param> +    <param> +      <key>time_source3</key> +      <value></value> +    </param> +    <param> +      <key>clock_source4</key> +      <value></value> +    </param> +    <param> +      <key>sd_spec4</key> +      <value></value> +    </param> +    <param> +      <key>time_source4</key> +      <value></value> +    </param> +    <param> +      <key>clock_source5</key> +      <value></value> +    </param> +    <param> +      <key>sd_spec5</key> +      <value></value> +    </param> +    <param> +      <key>time_source5</key> +      <value></value> +    </param> +    <param> +      <key>clock_source6</key> +      <value></value> +    </param> +    <param> +      <key>sd_spec6</key> +      <value></value> +    </param> +    <param> +      <key>time_source6</key> +      <value></value> +    </param> +    <param> +      <key>clock_source7</key> +      <value></value> +    </param> +    <param> +      <key>sd_spec7</key> +      <value></value> +    </param> +    <param> +      <key>time_source7</key> +      <value></value> +    </param> +    <param> +      <key>minoutbuf</key> +      <value>0</value> +    </param> +    <param> +      <key>nchan</key> +      <value>2</value> +    </param> +    <param> +      <key>num_mboards</key> +      <value>1</value> +    </param> +    <param> +      <key>type</key> +      <value>fc32</value> +    </param> +    <param> +      <key>samp_rate</key> +      <value>samp_rate</value> +    </param> +    <param> +      <key>hide_cmd_port</key> +      <value>False</value> +    </param> +    <param> +      <key>hide_lo_controls</key> +      <value>True</value> +    </param> +    <param> +      <key>stream_args</key> +      <value></value> +    </param> +    <param> +      <key>stream_chans</key> +      <value>[]</value> +    </param> +    <param> +      <key>sync</key> +      <value></value> +    </param> +    <param> +      <key>otw</key> +      <value></value> +    </param> +  </block> +  <block> +    <key>usrptest_phase_calc_ccf</key> +    <param> +      <key>alias</key> +      <value></value> +    </param> +    <param> +      <key>comment</key> +      <value></value> +    </param> +    <param> +      <key>affinity</key> +      <value></value> +    </param> +    <param> +      <key>_enabled</key> +      <value>True</value> +    </param> +    <param> +      <key>_coordinate</key> +      <value>(568, 408)</value> +    </param> +    <param> +      <key>_rotation</key> +      <value>0</value> +    </param> +    <param> +      <key>id</key> +      <value>usrptest_phase_calc_ccf_0</value> +    </param> +    <param> +      <key>maxoutbuf</key> +      <value>0</value> +    </param> +    <param> +      <key>minoutbuf</key> +      <value>0</value> +    </param> +  </block> +  <connection> +    <source_block_id>analog_sig_source_x_1</source_block_id> +    <sink_block_id>uhd_usrp_sink_1</sink_block_id> +    <source_key>0</source_key> +    <sink_key>0</sink_key> +  </connection> +  <connection> +    <source_block_id>analog_sig_source_x_1</source_block_id> +    <sink_block_id>uhd_usrp_sink_1</sink_block_id> +    <source_key>0</source_key> +    <sink_key>1</sink_key> +  </connection> +  <connection> +    <source_block_id>uhd_usrp_source_0</source_block_id> +    <sink_block_id>qtgui_time_sink_x_1</sink_block_id> +    <source_key>0</source_key> +    <sink_key>0</sink_key> +  </connection> +  <connection> +    <source_block_id>uhd_usrp_source_0</source_block_id> +    <sink_block_id>usrptest_phase_calc_ccf_0</sink_block_id> +    <source_key>0</source_key> +    <sink_key>0</sink_key> +  </connection> +  <connection> +    <source_block_id>uhd_usrp_source_0</source_block_id> +    <sink_block_id>qtgui_time_sink_x_1</sink_block_id> +    <source_key>1</source_key> +    <sink_key>1</sink_key> +  </connection> +  <connection> +    <source_block_id>uhd_usrp_source_0</source_block_id> +    <sink_block_id>usrptest_phase_calc_ccf_0</sink_block_id> +    <source_key>1</source_key> +    <sink_key>1</sink_key> +  </connection> +  <connection> +    <source_block_id>usrptest_phase_calc_ccf_0</source_block_id> +    <sink_block_id>qtgui_time_sink_x_0</sink_block_id> +    <source_key>0</source_key> +    <sink_key>0</sink_key> +  </connection> +</flow_graph> diff --git a/tools/gr-usrptest/grc/usrptest_measurement_sink_f.xml b/tools/gr-usrptest/grc/usrptest_measurement_sink_f.xml new file mode 100644 index 000000000..c681e457f --- /dev/null +++ b/tools/gr-usrptest/grc/usrptest_measurement_sink_f.xml @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<block> +  <name>measurement_sink_f</name> +  <key>usrptest_measurement_sink_f</key> +  <category>[usrptest]</category> +  <import>import usrptest</import> +  <make>usrptest.measurement_sink_f($num_samples, $)</make> +  <!-- Make one 'param' node for every Parameter you want settable from the GUI. +       Sub-nodes: +       * name +       * key (makes the value accessible as $keyname, e.g. in the make node) +       * type --> +  <param> +    <name>...</name> +    <key>...</key> +    <type>...</type> +  </param> + +  <!-- Make one 'sink' node per input. Sub-nodes: +       * name (an identifier for the GUI) +       * type +       * vlen +       * optional (set to 1 for optional inputs) --> +  <sink> +    <name>in</name> +    <type><!-- e.g. int, float, complex, byte, short, xxx_vector, ...--></type> +  </sink> + +  <!-- Make one 'source' node per output. Sub-nodes: +       * name (an identifier for the GUI) +       * type +       * vlen +       * optional (set to 1 for optional inputs) --> +  <source> +    <name>out</name> +    <type><!-- e.g. int, float, complex, byte, short, xxx_vector, ...--></type> +  </source> +</block> diff --git a/tools/gr-usrptest/grc/usrptest_phase_calc_ccf.xml b/tools/gr-usrptest/grc/usrptest_phase_calc_ccf.xml new file mode 100644 index 000000000..4c98f56eb --- /dev/null +++ b/tools/gr-usrptest/grc/usrptest_phase_calc_ccf.xml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<block> +  <name>Calculate phase diff</name> +  <key>usrptest_phase_calc_ccf</key> +  <category>[usrptest]</category> +  <import>import usrptest</import> +  <make>usrptest.phase_calc_ccf()</make> +  <sink> +    <name>in1</name> +    <type>complex</type> +  </sink> +  <sink> +    <name>in2</name> +    <type>complex</type> +  </sink> +  <source> +    <name>out</name> +    <type>float</type> +  </source> +</block> diff --git a/tools/gr-usrptest/include/usrptest/CMakeLists.txt b/tools/gr-usrptest/include/usrptest/CMakeLists.txt index 2d5ed3975..761a8bee4 100644 --- a/tools/gr-usrptest/include/usrptest/CMakeLists.txt +++ b/tools/gr-usrptest/include/usrptest/CMakeLists.txt @@ -22,5 +22,5 @@  ########################################################################  install(FILES      api.h -    DESTINATION include/usrptest +    measurement_sink_f.h DESTINATION include/usrptest  ) diff --git a/tools/gr-usrptest/include/usrptest/measurement_sink_f.h b/tools/gr-usrptest/include/usrptest/measurement_sink_f.h new file mode 100644 index 000000000..aaf1fb9d1 --- /dev/null +++ b/tools/gr-usrptest/include/usrptest/measurement_sink_f.h @@ -0,0 +1,61 @@ +/* -*- c++ -*- */ +/*  + * 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. + */ + + +#ifndef INCLUDED_USRPTEST_MEASUREMENT_SINK_F_H +#define INCLUDED_USRPTEST_MEASUREMENT_SINK_F_H + +#include <usrptest/api.h> +#include <gnuradio/sync_block.h> + +namespace gr { +  namespace usrptest { + +    /*! +     * \brief <+description of block+> +     * \ingroup usrptest +     * +     */ +    class USRPTEST_API measurement_sink_f : virtual public gr::sync_block +    { +     public: +      typedef boost::shared_ptr<measurement_sink_f> sptr; + +      /*! +       * \brief Return a shared_ptr to a new instance of usrptest::measurement_sink_f. +       * +       * To avoid accidental use of raw pointers, usrptest::measurement_sink_f's +       * constructor is in a private implementation +       * class. usrptest::measurement_sink_f::make is the public interface for +       * creating new instances. +       */ +      static sptr make(int num_samples,int runs); +      virtual std::vector<float> get_avg() const = 0; +      virtual std::vector<float> get_stddev() const = 0; +      virtual int get_run() const = 0; +      virtual void start_run() = 0; + +    }; + +  } // namespace usrptest +} // namespace gr + +#endif /* INCLUDED_USRPTEST_MEASUREMENT_SINK_F_H */ + diff --git a/tools/gr-usrptest/lib/CMakeLists.txt b/tools/gr-usrptest/lib/CMakeLists.txt index dd44b7f26..2d8f0fe16 100644 --- a/tools/gr-usrptest/lib/CMakeLists.txt +++ b/tools/gr-usrptest/lib/CMakeLists.txt @@ -26,6 +26,7 @@ include_directories(${Boost_INCLUDE_DIR})  link_directories(${Boost_LIBRARY_DIRS})  list(APPEND usrptest_sources +    measurement_sink_f_impl.cc  )  set(usrptest_sources "${usrptest_sources}" PARENT_SCOPE) diff --git a/tools/gr-usrptest/lib/measurement_sink_f_impl.cc b/tools/gr-usrptest/lib/measurement_sink_f_impl.cc new file mode 100644 index 000000000..58faccb9a --- /dev/null +++ b/tools/gr-usrptest/lib/measurement_sink_f_impl.cc @@ -0,0 +1,124 @@ +/* -*- c++ -*- */ +/*  + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gnuradio/io_signature.h> +#include "measurement_sink_f_impl.h" + +namespace gr { +  namespace usrptest { + +    measurement_sink_f::sptr +    measurement_sink_f::make(int num_samples, int runs) +    { +      return gnuradio::get_initial_sptr +        (new measurement_sink_f_impl(num_samples, runs)); + +    } + +    /* +     * The private constructor +     */ +    measurement_sink_f_impl::measurement_sink_f_impl(int num_samples, int runs) +      : gr::sync_block("measurement_sink_f", +              gr::io_signature::make(1, 1, sizeof(float)), +              gr::io_signature::make(0, 0, 0)), +        d_runs(runs), +        d_nsamples(num_samples) +    { +      d_curr_run = 0; // number of completed measurement runs +      d_curr_avg = 0.0f; // accumulated average +      d_curr_M2 = 0.0f; // accumulated M2 +      d_run = false; // true if a measurement is currently recorded +      d_curr_sample = 0; // current sample count +    } + +    /* +     * Our virtual destructor. +     */ +    measurement_sink_f_impl::~measurement_sink_f_impl() +    { +    } + +    int +    measurement_sink_f_impl::work(int noutput_items, +        gr_vector_const_void_star &input_items, +        gr_vector_void_star &output_items) +    { +      const float *in = (const float *) input_items[0]; +      if ((d_curr_run < d_runs)&&d_run){ //check if we need to record data +        const int max_items = std::min(noutput_items, d_nsamples-d_curr_sample); // calculate number of samples we have to take into account +        for (int item=0; item < max_items;++item){ +          ++d_curr_sample; +          inc_both(in[item]); +        } +        if (d_curr_sample == d_nsamples) { +          d_avg.push_back(d_curr_avg); +          d_stddev.push_back(std::sqrt(d_curr_M2/(float)(d_curr_sample - 1))); +          ++d_curr_run; +          d_run = false; +          d_curr_sample = 0; +          d_curr_avg = 0.0f; +          d_curr_M2 = 0.0f; +        } +      } +      return noutput_items; +    } + + +    void +    measurement_sink_f_impl::inc_both(const float new_val) +    { +      float delta = new_val - d_curr_avg; +      d_curr_avg = d_curr_avg + delta/(float)(d_curr_sample); +      d_curr_M2 = d_curr_M2 + delta*(new_val - d_curr_avg); +    } + +     +    void +    measurement_sink_f_impl::start_run() +    { +      d_run = true; +    } + +    std::vector<float> +    measurement_sink_f_impl::get_avg() const +    { +      return d_avg; +    } + +    std::vector<float> +    measurement_sink_f_impl::get_stddev() const +    { +      return d_stddev; +    } + +    int +    measurement_sink_f_impl::get_run() const +    { +      return d_curr_run; +    } + +  } /* namespace usrptest */ +} /* namespace gr */ + diff --git a/tools/gr-usrptest/lib/measurement_sink_f_impl.h b/tools/gr-usrptest/lib/measurement_sink_f_impl.h new file mode 100644 index 000000000..4d63adfa2 --- /dev/null +++ b/tools/gr-usrptest/lib/measurement_sink_f_impl.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/*  + * 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. + */ + +#ifndef INCLUDED_USRPTEST_MEASUREMENT_SINK_F_IMPL_H +#define INCLUDED_USRPTEST_MEASUREMENT_SINK_F_IMPL_H + +#include <usrptest/measurement_sink_f.h> + +namespace gr { +  namespace usrptest { + +    class measurement_sink_f_impl : public measurement_sink_f +    { +     private: +       std::vector< float > d_avg; +       std::vector< float > d_stddev; +       bool d_run; +       int d_runs; +       int d_nsamples; +       int d_curr_sample; +       int d_curr_run; +       float d_curr_avg; +       float d_curr_M2; +       void inc_both(const float new_val); + + +     public: +      measurement_sink_f_impl(int num_samples, int runs); +      ~measurement_sink_f_impl(); +      std::vector<float> get_avg() const; +      std::vector<float> get_stddev() const; +      int get_run() const; +      void start_run(); + +      // Where all the action really happens +      int work(int noutput_items, +         gr_vector_const_void_star &input_items, +         gr_vector_void_star &output_items); +    }; + +  } // namespace usrptest +} // namespace gr + +#endif /* INCLUDED_USRPTEST_MEASUREMENT_SINK_F_IMPL_H */ + diff --git a/tools/gr-usrptest/lib/qa_usrptest.cc b/tools/gr-usrptest/lib/qa_usrptest.cc new file mode 100644 index 000000000..c8e6495ae --- /dev/null +++ b/tools/gr-usrptest/lib/qa_usrptest.cc @@ -0,0 +1,36 @@ +/* + * Copyright 2012 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. + */ + +/* + * This class gathers together all the test cases for the gr-filter + * directory into a single test suite.  As you create new test cases, + * add them here. + */ + +#include "qa_usrptest.h" + +CppUnit::TestSuite * +qa_usrptest::suite() +{ +  CppUnit::TestSuite *s = new CppUnit::TestSuite("usrptest"); + +  return s; +} diff --git a/tools/gr-usrptest/lib/qa_usrptest.h b/tools/gr-usrptest/lib/qa_usrptest.h new file mode 100644 index 000000000..94ce3f33b --- /dev/null +++ b/tools/gr-usrptest/lib/qa_usrptest.h @@ -0,0 +1,38 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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. + */ + +#ifndef _QA_USRPTEST_H_ +#define _QA_USRPTEST_H_ + +#include <gnuradio/attributes.h> +#include <cppunit/TestSuite.h> + +//! collect all the tests for the gr-filter directory + +class __GR_ATTR_EXPORT qa_usrptest +{ + public: +  //! return suite of tests for all of gr-filter directory +  static CppUnit::TestSuite *suite(); +}; + +#endif /* _QA_USRPTEST_H_ */ diff --git a/tools/gr-usrptest/lib/test_usrptest.cc b/tools/gr-usrptest/lib/test_usrptest.cc new file mode 100644 index 000000000..808638cdf --- /dev/null +++ b/tools/gr-usrptest/lib/test_usrptest.cc @@ -0,0 +1,48 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <cppunit/TextTestRunner.h> +#include <cppunit/XmlOutputter.h> + +#include <gnuradio/unittests.h> +#include "qa_usrptest.h" +#include <iostream> +#include <fstream> + +int +main (int argc, char **argv) +{ +  CppUnit::TextTestRunner runner; +  std::ofstream xmlfile(get_unittest_path("usrptest.xml").c_str()); +  CppUnit::XmlOutputter *xmlout = new CppUnit::XmlOutputter(&runner.result(), xmlfile); + +  runner.addTest(qa_usrptest::suite()); +  runner.setOutputter(xmlout); + +  bool was_successful = runner.run("", false); + +  return was_successful ? 0 : 1; +} diff --git a/tools/gr-usrptest/python/CMakeLists.txt b/tools/gr-usrptest/python/CMakeLists.txt index 4afda600e..ba3d12394 100644 --- a/tools/gr-usrptest/python/CMakeLists.txt +++ b/tools/gr-usrptest/python/CMakeLists.txt @@ -31,15 +31,21 @@ endif()  GR_PYTHON_INSTALL(      FILES      __init__.py -    parsers.py -    selftest_fg.py +    functions.py      phase_calc_ccf.py DESTINATION ${GR_PYTHON_DIR}/usrptest  ) +add_subdirectory(flowgraphs) +add_subdirectory(labview_control) +add_subdirectory(rts_tests) +  ########################################################################  # Handle the unit tests  ########################################################################  include(GrTest) +GR_ADD_TEST(qa_phasealignment ${PYTHON_EXECUTABLE} +    ${CMAKE_CURRENT_SOURCE_DIR}/qa_phasealignment.py)  set(GR_TEST_TARGET_DEPS gnuradio-usrptest)  set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/swig) +GR_ADD_TEST(qa_measurement_sink_f ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_measurement_sink_f.py) diff --git a/tools/gr-usrptest/python/flowgraphs/CMakeLists.txt b/tools/gr-usrptest/python/flowgraphs/CMakeLists.txt new file mode 100644 index 000000000..7ea94b505 --- /dev/null +++ b/tools/gr-usrptest/python/flowgraphs/CMakeLists.txt @@ -0,0 +1,28 @@ +# 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 +    selftest_fg.py +    phasealignment_fg.py DESTINATION ${GR_PYTHON_DIR}/usrptest/flowgraphs +) diff --git a/tools/gr-usrptest/python/flowgraphs/__init__.py b/tools/gr-usrptest/python/flowgraphs/__init__.py new file mode 100644 index 000000000..048e5638a --- /dev/null +++ b/tools/gr-usrptest/python/flowgraphs/__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/flowgraphs/phasealignment_fg.py b/tools/gr-usrptest/python/flowgraphs/phasealignment_fg.py new file mode 100644 index 000000000..f120e2421 --- /dev/null +++ b/tools/gr-usrptest/python/flowgraphs/phasealignment_fg.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python2 + +from gnuradio import gr +from gnuradio import uhd +from gnuradio import analog +from usrptest import phase_calc_ccf, measurement_sink_f +from usrptest.functions import log_level +from random import uniform +from ast import literal_eval +import copy +import logging +import sys + + +class phasealignment_fg(gr.top_block): +    def __init__(self, uhd_app): +        gr.top_block.__init__(self, "Calculate dphi for all USRPs (Rx only)") +        ############################## +        #   Block dicts +        ############################## +        self.log = logging.getLogger(__name__) +        [self.log.removeHandler(h) for h in self.log.handlers] +        self.log.addHandler(logging.StreamHandler(sys.stdout)) +        self.log.setLevel(log_level(uhd_app.args.log_level)) +        self.rx_streams = list() +        self.phase_diff_calc = list() +        self.measurement_sink = list() +        self.uhd_app = copy.copy(uhd_app) +        self.tx_app = copy.copy(uhd_app) +        self.samp_rate = uhd_app.args.samp_rate +        # Create all devices specified in --receiver +        # Create all remaining blocks and connect devices to the first port and +        # sink +        self.uhd_app.args.num_chan = len(self.uhd_app.args.channels) +        self.log.info('setting up usrp....') +        ############################## +        #  Setup RX +        ############################## +        self.log.debug("RX-Setup with args: {}".format(self.uhd_app.args)) +        self.uhd_app.setup_usrp(uhd.usrp_source, self.uhd_app.args) +        if self.uhd_app.args.measurement_setup is not None: +            self.measurement_channels = self.uhd_app.args.measurement_setup.strip( +            ).split(',') +            # make sure every channels is listed in measurement_channels at least once +            if len(set( +                    self.measurement_channels)) != self.uhd_apps.args.num_chan: +                self.uhd_app.vprint( +                    "[{prefix}] Number of measurement channels has to be the number of used channels." +                ) +                self.uhd_app.exit(1) +            self.measurement_channels = [self.uhd_app.args.channels.index(m) for m in self.measurement_channels] +        else: +            self.measurement_channels = range(self.uhd_app.args.num_chan) + +        self.measurement_channels_names = list() +        for chan in self.measurement_channels: +            usrp_info = self.uhd_app.usrp.get_usrp_info(chan) +            self.measurement_channels_names.append("_".join( +                [usrp_info['mboard_serial'], usrp_info['rx_serial']])) + +        #Connect channels to first port of d_phi_calc_block and to measurement_sink +        for num, chan in enumerate(self.measurement_channels[:-1]): +            self.phase_diff_calc.append(phase_calc_ccf()) +            self.measurement_sink.append( +                measurement_sink_f( +                    int(self.uhd_app.args.samp_rate * +                        self.uhd_app.args.duration), self.uhd_app.args.runs)) +            self.connect((self.uhd_app.usrp, chan), +                         (self.phase_diff_calc[num], 0)) +            self.connect((self.phase_diff_calc[num], 0), +                         (self.measurement_sink[num], 0)) +        # Connect devices to second port of d_phi_block +        for num, chan in enumerate(self.measurement_channels[1:]): +            self.connect((self.uhd_app.usrp, chan), +                         (self.phase_diff_calc[num], 1)) +        ############################## +        #  Setup TX +        ############################## +        if self.uhd_app.args.tx_channels is not None: +            self.tx_app.args.antenna = self.tx_app.args.tx_antenna +            self.tx_app.args.channels = [ +                int(chan.strip()) +                for chan in self.tx_app.args.tx_channels.split(',') +            ] +            self.tx_app.usrp = None +            self.log.debug("TX-Setup with args: {}".format(self.tx_app.args)) +            self.tx_app.setup_usrp(uhd.usrp_sink, self.tx_app.args) +            self.siggen = analog.sig_source_c(self.samp_rate, +                                              analog.GR_COS_WAVE, +                                              self.tx_app.args.tx_offset, 1.0) +            for chan in range(len(self.tx_app.channels)): +                self.connect((self.siggen, 0), (self.tx_app.usrp, chan)) + + +    def get_samp_rate(self): +        return self.samp_rate + +    def set_samp_rate(self, samp_rate): +        self.samp_rate = samp_rate + +    def retune_frequency(self, band_num=1, bands=1): +        ref_chan = self.uhd_app.channels[0] +        freq_range = literal_eval( +            self.uhd_app.usrp.get_freq_range(ref_chan).__str__( +            ))  # returns tuple with (start_freq, end_freq, step) + +        if bands > 1: +            bw = (freq_range[1] - freq_range[0])/bands +            freq_range = list(freq_range) +            freq_range[0] = freq_range[0] + ((band_num-1) % bands)*bw +            freq_range[1] = freq_range[0] + bw + +        retune_freq = uniform(freq_range[0], freq_range[1]) +        self.log.info('tune all channels to: {:f} MHz'.format(retune_freq / +                                                              1e6)) +        self.uhd_app.set_freq(retune_freq) +        self.log.info('tune all channels to: {:f} MHz'.format( +            self.uhd_app.args.freq / 1e6)) +        self.uhd_app.set_freq(self.uhd_app.args.freq) diff --git a/tools/gr-usrptest/python/flowgraphs/selftest_fg.py b/tools/gr-usrptest/python/flowgraphs/selftest_fg.py new file mode 100644 index 000000000..cdfc35e74 --- /dev/null +++ b/tools/gr-usrptest/python/flowgraphs/selftest_fg.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python + +from gnuradio import blocks +from gnuradio import gr +from gnuradio import uhd +from usrptest import phase_calc_ccf +from gnuradio.uhd.uhd_app import UHDApp +import numpy as np + +class selftest_fg(gr.top_block): + +    def __init__(self, freq, samp_rate, dphase, devices=list()): +        gr.top_block.__init__(self, "Generate Signal extract phase") + +        ################################################## +        # Variables +        ################################################## +        self.samp_rate = samp_rate +        self.freq = 10e3 +        self.devices = devices +        self.dphase = dphase +        self.tx_gain = 50 +        self.rx_gain = 50 +        self.center_freq = freq +        self.omega = 2*np.pi*self.freq +        self.steps = np.arange( +            self.samp_rate)*float(self.omega)/float(self.samp_rate) +        self.reference = self.complex_sine(self.steps) +        self.test_signal = self.complex_sine(self.steps+0.5*np.pi) +        self.device_test = False + +        ################################################## +        # Block dicts +        ################################################## +        self.rx_devices = dict() +        self.tx_devices = dict() +        self.sink_dict = dict() +        self.phase_dict = dict() +        self.reference_source = blocks.vector_source_c(self.reference) + +        if len(self.devices): +            ################################################## +            # Devices +            ################################################## +            self.device_test = True +            #To reuse existing setup_usrp() command +            for device in self.devices: +                # Create and configure all devices +                self.rx_devices[device] = uhd.usrp_source( +                    device, uhd.stream_args( +                        cpu_format="fc32", channel=range(1))) +                self.tx_devices[device] = uhd.usrp_sink( +                    device, uhd.stream_args( +                        cpu_format="fc32", channel=range(1))) +                self.rx_devices[device].set_samp_rate(self.samp_rate) +                self.rx_devices[device].set_center_freq(self.center_freq, 0) +                self.rx_devices[device].set_gain(self.rx_gain, 0) +                self.tx_devices[device].set_samp_rate(self.samp_rate) +                self.tx_devices[device].set_center_freq(self.center_freq, 0) +                self.tx_devices[device].set_gain(self.tx_gain, 0) +                self.sink_dict[device] = blocks.vector_sink_f() +                self.phase_dict[device] = phase_calc_ccf( +                    self.samp_rate, self.freq) +            for device in self.tx_devices.values(): +                self.connect((self.reference_source, 0), (device, 0)) + +            for device_key in self.rx_devices.keys(): +                self.connect( +                    (self.rx_devices[device_key], 0), (self.phase_dict[device_key], 0)) +                self.connect((self.reference_source, 0), +                             (self.phase_dict[device_key], 1)) +                self.connect( +                    (self.phase_dict[device_key], 0), (self.sink_dict[device_key], 0)) +            # Debug options +            # self.sink_list.append(blocks.vector_sink_c()) +            #self.connect((device, 0), (self.sink_list[-1], 0)) +            # self.sink_list.append(blocks.vector_sink_c()) +            #self.connect((self.reference_source, 0), (self.sink_list[-1], 0)) +        else: +            ################################################## +            # Blocks +            ################################################## +            self.result = blocks.vector_sink_f(1) +            self.test_source = blocks.vector_source_c(self.test_signal) +            self.block_phase_calc = phase_calc_ccf( +                self.samp_rate, self.freq) + +            ################################################## +            # Connections +            ################################################## +            self.connect((self.reference_source, 0), (self.block_phase_calc, 1)) +            self.connect((self.test_source, 0), (self.block_phase_calc, 0)) +            self.connect((self.block_phase_calc, 0), (self.result, 0)) +    def complex_sine(self, steps): +        return np.exp(1j*steps) + +    def get_samp_rate(self): +        return self.samp_rate + +    def set_samp_rate(self, samp_rate): +        self.samp_rate = samp_rate + +    def run(self): +        self.start() +        self.wait() +        if self.device_test: +            data = dict() +            for device_key in self.sink_dict.keys(): +                curr_data = self.sink_dict[device_key].data() +                curr_data = curr_data[int(0.2*self.samp_rate):-int(0.2*self.samp_rate)] +                phase_avg = np.average(curr_data) +                if (np.max(curr_data) < phase_avg+self.dphase*0.5) and (np.min(curr_data) > phase_avg-self.dphase*0.5): +                    data[device_key] = phase_avg +                else: +                    print("Error phase not settled") + +            #Debug +            # plt.ylim(-1, 1) +            # plt.xlim(self.samp_rate/2.), (self.samp_rate/2.)+1000) +            #for key in data: +            #    plt.plot(data[key]) +        return data 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()) diff --git a/tools/gr-usrptest/python/phase_calc_ccf.py b/tools/gr-usrptest/python/phase_calc_ccf.py new file mode 100644 index 000000000..fe3cf55a8 --- /dev/null +++ b/tools/gr-usrptest/python/phase_calc_ccf.py @@ -0,0 +1,47 @@ +#!/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. +# + +from gnuradio import gr +from gnuradio import blocks +import numpy as np + + +class phase_calc_ccf(gr.hier_block2): +    """ +    docstring for block phase_calc_ccf +    """ + +    def __init__(self): +        gr.hier_block2.__init__( +            self, +            "phase_calc_ccf", +            gr.io_signature(2, 2, gr.sizeof_gr_complex),  # Input signature +            gr.io_signature(1, 1, gr.sizeof_float))  # Output signature +        self.block = dict() +        self.block['mult_conj'] = blocks.multiply_conjugate_cc() +        self.block['arg'] = blocks.complex_to_arg() +        self.block['mult_const'] = blocks.multiply_const_ff(180.0 / np.pi) + +        self.connect((self, 0), (self.block['mult_conj'], 0)) +        self.connect((self, 1), (self.block['mult_conj'], 1)) +        self.connect((self.block['mult_conj'], 0), (self.block['arg'], 0)) +        self.connect((self.block['arg'], 0), (self.block['mult_const'], 0)) +        self.connect((self.block['mult_const'], 0), (self, 0)) diff --git a/tools/gr-usrptest/python/qa_measurement_sink_f.py b/tools/gr-usrptest/python/qa_measurement_sink_f.py new file mode 100755 index 000000000..ceb9913ae --- /dev/null +++ b/tools/gr-usrptest/python/qa_measurement_sink_f.py @@ -0,0 +1,41 @@ +#!/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. +#  + +from gnuradio import gr, gr_unittest +from gnuradio import blocks +import usrptest_swig as usrptest + +class qa_measurement_sink_f (gr_unittest.TestCase): + +    def setUp (self): +        self.tb = gr.top_block () + +    def tearDown (self): +        self.tb = None + +    def test_001_t (self): +        # set up fg +        self.tb.run () +        # check data + + +if __name__ == '__main__': +    gr_unittest.run(qa_measurement_sink_f, "qa_measurement_sink_f.xml") 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. diff --git a/tools/gr-usrptest/swig/usrptest_swig.i b/tools/gr-usrptest/swig/usrptest_swig.i index c6988262e..273b7c866 100644 --- a/tools/gr-usrptest/swig/usrptest_swig.i +++ b/tools/gr-usrptest/swig/usrptest_swig.i @@ -8,6 +8,9 @@  %include "usrptest_swig_doc.i"  %{ +#include "usrptest/measurement_sink_f.h"  %} +%include "usrptest/measurement_sink_f.h" +GR_SWIG_BLOCK_MAGIC2(usrptest, measurement_sink_f);  | 
