summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gnuradio-core/src/examples/ctrlport/comparing_resamplers.grc390
-rw-r--r--gnuradio-core/src/examples/ctrlport/pfb_sync_test-qt.grc521
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block.cc122
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block.h50
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block_detail.cc75
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block_detail.h13
-rwxr-xr-xgnuradio-core/src/python/gnuradio/ctrlport/gr-perf-monitorx710
-rw-r--r--gr-blocks/grc/blocks_probe_signal_vx.xml2
8 files changed, 1621 insertions, 262 deletions
diff --git a/gnuradio-core/src/examples/ctrlport/comparing_resamplers.grc b/gnuradio-core/src/examples/ctrlport/comparing_resamplers.grc
new file mode 100644
index 0000000000..a48b2d21d2
--- /dev/null
+++ b/gnuradio-core/src/examples/ctrlport/comparing_resamplers.grc
@@ -0,0 +1,390 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+ <timestamp>Thu Mar 14 15:16:20 2013</timestamp>
+ <block>
+ <key>options</key>
+ <param>
+ <key>id</key>
+ <value>comparing_resamplers</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value></value>
+ </param>
+ <param>
+ <key>author</key>
+ <value></value>
+ </param>
+ <param>
+ <key>description</key>
+ <value></value>
+ </param>
+ <param>
+ <key>window_size</key>
+ <value>1280, 1024</value>
+ </param>
+ <param>
+ <key>generate_options</key>
+ <value>no_gui</value>
+ </param>
+ <param>
+ <key>category</key>
+ <value>Custom</value>
+ </param>
+ <param>
+ <key>run_options</key>
+ <value>prompt</value>
+ </param>
+ <param>
+ <key>run</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>max_nouts</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>realtime_scheduling</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(10, 10)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_throttle</key>
+ <param>
+ <key>id</key>
+ <value>blocks_throttle_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>samples_per_second</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(191, 125)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>gr_ctrlport_probe2_c</key>
+ <param>
+ <key>id</key>
+ <value>probe_arc_resamp</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>name</key>
+ <value>arb_resampler</value>
+ </param>
+ <param>
+ <key>desc</key>
+ <value>PFB Arbitrary Resampler</value>
+ </param>
+ <param>
+ <key>len</key>
+ <value>1024</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(9, 296)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>180</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>resamp_rate</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>1.25</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(272, 9)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>pfb_arb_resampler_xxx</key>
+ <param>
+ <key>id</key>
+ <value>pfb_arb_resampler_xxx_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>ccf</value>
+ </param>
+ <param>
+ <key>rrate</key>
+ <value>resamp_rate</value>
+ </param>
+ <param>
+ <key>taps</key>
+ <value></value>
+ </param>
+ <param>
+ <key>nfilts</key>
+ <value>32</value>
+ </param>
+ <param>
+ <key>atten</key>
+ <value>60</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(305, 280)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>180</value>
+ </param>
+ </block>
+ <block>
+ <key>gr_ctrlport_probe2_c</key>
+ <param>
+ <key>id</key>
+ <value>probe_frac_interp</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>name</key>
+ <value>fractional_interp</value>
+ </param>
+ <param>
+ <key>desc</key>
+ <value>Fractional Interpolator</value>
+ </param>
+ <param>
+ <key>len</key>
+ <value>1024</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(10, 204)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>180</value>
+ </param>
+ </block>
+ <block>
+ <key>fractional_interpolator_xx</key>
+ <param>
+ <key>id</key>
+ <value>fractional_interpolator_xx_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>phase_shift</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>interp_ratio</key>
+ <value>1.0/resamp_rate</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(354, 212)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>180</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>30e6</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(181, 10)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>analog_sig_source_x</key>
+ <param>
+ <key>id</key>
+ <value>analog_sig_source_x_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</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>
+ <param>
+ <key>freq</key>
+ <value>samp_rate/10</value>
+ </param>
+ <param>
+ <key>amp</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>offset</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(11, 93)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>channels_channel_model</key>
+ <param>
+ <key>id</key>
+ <value>channels_channel_model_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>noise_voltage</key>
+ <value>0.1</value>
+ </param>
+ <param>
+ <key>freq_offset</key>
+ <value>0.0</value>
+ </param>
+ <param>
+ <key>epsilon</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>taps</key>
+ <value>[1,]</value>
+ </param>
+ <param>
+ <key>seed</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(382, 93)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <connection>
+ <source_block_id>analog_sig_source_x_0</source_block_id>
+ <sink_block_id>blocks_throttle_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_throttle_0</source_block_id>
+ <sink_block_id>channels_channel_model_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>channels_channel_model_0</source_block_id>
+ <sink_block_id>pfb_arb_resampler_xxx_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>channels_channel_model_0</source_block_id>
+ <sink_block_id>fractional_interpolator_xx_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>pfb_arb_resampler_xxx_0</source_block_id>
+ <sink_block_id>probe_arc_resamp</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>fractional_interpolator_xx_0</source_block_id>
+ <sink_block_id>probe_frac_interp</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+</flow_graph>
diff --git a/gnuradio-core/src/examples/ctrlport/pfb_sync_test-qt.grc b/gnuradio-core/src/examples/ctrlport/pfb_sync_test-qt.grc
index 5ccc65140c..80d0c8ffa8 100644
--- a/gnuradio-core/src/examples/ctrlport/pfb_sync_test-qt.grc
+++ b/gnuradio-core/src/examples/ctrlport/pfb_sync_test-qt.grc
@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='ASCII'?>
<flow_graph>
- <timestamp>Tue Feb 26 14:26:03 2013</timestamp>
+ <timestamp>Thu Mar 14 14:41:57 2013</timestamp>
<block>
<key>options</key>
<param>
@@ -64,7 +64,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>graymap</value>
+ <value>sps</value>
</param>
<param>
<key>_enabled</key>
@@ -72,11 +72,11 @@
</param>
<param>
<key>value</key>
- <value>[[3,1,0,2]]</value>
+ <value>2</value>
</param>
<param>
<key>_coordinate</key>
- <value>(32, 387)</value>
+ <value>(105, 126)</value>
</param>
<param>
<key>_rotation</key>
@@ -87,7 +87,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>amps</value>
+ <value>samp_rate</value>
</param>
<param>
<key>_enabled</key>
@@ -95,11 +95,11 @@
</param>
<param>
<key>value</key>
- <value>[1]</value>
+ <value>300000</value>
</param>
<param>
<key>_coordinate</key>
- <value>(32, 451)</value>
+ <value>(14, 124)</value>
</param>
<param>
<key>_rotation</key>
@@ -107,22 +107,22 @@
</param>
</block>
<block>
- <key>variable</key>
+ <key>import</key>
<param>
<key>id</key>
- <value>nfilts</value>
+ <value>import_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>value</key>
- <value>32</value>
+ <key>import</key>
+ <value>import random, math, cmath</value>
</param>
<param>
<key>_coordinate</key>
- <value>(99, 451)</value>
+ <value>(14, 77)</value>
</param>
<param>
<key>_rotation</key>
@@ -130,22 +130,22 @@
</param>
</block>
<block>
- <key>variable</key>
+ <key>ctrlport_monitor</key>
<param>
<key>id</key>
- <value>sps</value>
+ <value>ctrlport_monitor_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>value</key>
- <value>2</value>
+ <key>en</key>
+ <value>True</value>
</param>
<param>
<key>_coordinate</key>
- <value>(105, 126)</value>
+ <value>(175, 10)</value>
</param>
<param>
<key>_rotation</key>
@@ -153,22 +153,34 @@
</param>
</block>
<block>
- <key>variable</key>
+ <key>gr_vector_source_x</key>
<param>
<key>id</key>
- <value>samp_rate</value>
+ <value>gr_vector_source_x_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>value</key>
- <value>300000</value>
+ <key>type</key>
+ <value>byte</value>
+ </param>
+ <param>
+ <key>vector</key>
+ <value>0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50</value>
+ </param>
+ <param>
+ <key>repeat</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
</param>
<param>
<key>_coordinate</key>
- <value>(14, 124)</value>
+ <value>(190, 71)</value>
</param>
<param>
<key>_rotation</key>
@@ -176,22 +188,34 @@
</param>
</block>
<block>
- <key>import</key>
+ <key>blocks_packed_to_unpacked_xx</key>
<param>
<key>id</key>
- <value>import_0</value>
+ <value>blocks_packed_to_unpacked_xx_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>import</key>
- <value>import random, math, cmath</value>
+ <key>type</key>
+ <value>byte</value>
+ </param>
+ <param>
+ <key>bits_per_chunk</key>
+ <value>8</value>
+ </param>
+ <param>
+ <key>endianness</key>
+ <value>gr.GR_MSB_FIRST</value>
+ </param>
+ <param>
+ <key>num_ports</key>
+ <value>1</value>
</param>
<param>
<key>_coordinate</key>
- <value>(14, 77)</value>
+ <value>(419, 10)</value>
</param>
<param>
<key>_rotation</key>
@@ -199,81 +223,77 @@
</param>
</block>
<block>
- <key>variable_qtgui_range</key>
+ <key>blocks_throttle</key>
<param>
<key>id</key>
- <value>phase</value>
+ <value>blocks_throttle_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>label</key>
- <value>Phase</value>
- </param>
- <param>
- <key>value</key>
- <value>0.5</value>
+ <key>type</key>
+ <value>byte</value>
</param>
<param>
- <key>start</key>
- <value>0</value>
+ <key>samples_per_second</key>
+ <value>samp_rate</value>
</param>
<param>
- <key>stop</key>
- <value>2</value>
+ <key>vlen</key>
+ <value>1</value>
</param>
<param>
- <key>step</key>
- <value>0.01</value>
+ <key>_coordinate</key>
+ <value>(436, 97)</value>
</param>
<param>
- <key>widget</key>
- <value>counter_slider</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>digital_psk_mod</key>
<param>
- <key>orient</key>
- <value>Qt.Horizontal</value>
+ <key>id</key>
+ <value>digital_psk_mod_0</value>
</param>
<param>
- <key>min_len</key>
- <value>200</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>gui_hint</key>
- <value></value>
+ <key>constellation_points</key>
+ <value>4</value>
</param>
<param>
- <key>_coordinate</key>
- <value>(175, 387)</value>
+ <key>mod_code</key>
+ <value>"gray"</value>
</param>
<param>
- <key>_rotation</key>
- <value>0</value>
+ <key>differential</key>
+ <value>True</value>
</param>
- </block>
- <block>
- <key>gr_null_sink</key>
<param>
- <key>id</key>
- <value>gr_null_sink_0</value>
+ <key>samples_per_symbol</key>
+ <value>sps</value>
</param>
<param>
- <key>_enabled</key>
- <value>True</value>
+ <key>excess_bw</key>
+ <value>0.35</value>
</param>
<param>
- <key>type</key>
- <value>complex</value>
+ <key>verbose</key>
+ <value>False</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>log</key>
+ <value>False</value>
</param>
<param>
<key>_coordinate</key>
- <value>(939, 313)</value>
+ <value>(627, 65)</value>
</param>
<param>
<key>_rotation</key>
@@ -281,54 +301,50 @@
</param>
</block>
<block>
- <key>variable_qtgui_range</key>
+ <key>digital_pfb_clock_sync_xxx</key>
<param>
<key>id</key>
- <value>noise</value>
+ <value>digital_pfb_clock_sync_xxx_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>label</key>
- <value>Noise</value>
- </param>
- <param>
- <key>value</key>
- <value>0.050</value>
+ <key>type</key>
+ <value>ccf</value>
</param>
<param>
- <key>start</key>
- <value>0.0001</value>
+ <key>sps</key>
+ <value>sps</value>
</param>
<param>
- <key>stop</key>
- <value>2</value>
+ <key>loop_bw</key>
+ <value>2*3.14/100.0</value>
</param>
<param>
- <key>step</key>
- <value>0.01</value>
+ <key>taps</key>
+ <value>firdes.root_raised_cosine(nfilts, nfilts,1.0/sps, 0.35, int(22*sps*nfilts))</value>
</param>
<param>
- <key>widget</key>
- <value>counter_slider</value>
+ <key>filter_size</key>
+ <value>nfilts</value>
</param>
<param>
- <key>orient</key>
- <value>Qt.Horizontal</value>
+ <key>init_phase</key>
+ <value>nfilts/2</value>
</param>
<param>
- <key>min_len</key>
- <value>200</value>
+ <key>max_dev</key>
+ <value>1.5</value>
</param>
<param>
- <key>gui_hint</key>
- <value></value>
+ <key>osps</key>
+ <value>1</value>
</param>
<param>
<key>_coordinate</key>
- <value>(316, 389)</value>
+ <value>(339, 195)</value>
</param>
<param>
<key>_rotation</key>
@@ -336,58 +352,68 @@
</param>
</block>
<block>
- <key>qtgui_const_sink_x</key>
+ <key>variable</key>
<param>
<key>id</key>
- <value>qtgui_const_sink_x_0</value>
+ <value>nfilts</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>complex</value>
+ <key>value</key>
+ <value>32</value>
</param>
<param>
- <key>name</key>
- <value>QT GUI Plot</value>
+ <key>_coordinate</key>
+ <value>(74, 390)</value>
</param>
<param>
- <key>size</key>
- <value>1024</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>variable</key>
<param>
- <key>ymin</key>
- <value>-2</value>
+ <key>id</key>
+ <value>amps</value>
</param>
<param>
- <key>ymax</key>
- <value>2</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>xmin</key>
- <value>-2</value>
+ <key>value</key>
+ <value>[1]</value>
</param>
<param>
- <key>xmax</key>
- <value>2</value>
+ <key>_coordinate</key>
+ <value>(7, 390)</value>
</param>
<param>
- <key>nconnections</key>
- <value>2</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>variable</key>
<param>
- <key>update_time</key>
- <value>0.10</value>
+ <key>id</key>
+ <value>graymap</value>
</param>
<param>
- <key>gui_hint</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>[[3,1,0,2]]</value>
</param>
<param>
<key>_coordinate</key>
- <value>(949, 232)</value>
+ <value>(7, 326)</value>
</param>
<param>
<key>_rotation</key>
@@ -395,50 +421,54 @@
</param>
</block>
<block>
- <key>digital_pfb_clock_sync_xxx</key>
+ <key>variable_qtgui_range</key>
<param>
<key>id</key>
- <value>digital_pfb_clock_sync_xxx_0</value>
+ <value>phase</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>ccf</value>
+ <key>label</key>
+ <value>Phase</value>
</param>
<param>
- <key>sps</key>
- <value>sps</value>
+ <key>value</key>
+ <value>0.5</value>
</param>
<param>
- <key>loop_bw</key>
- <value>2*3.14/100.0</value>
+ <key>start</key>
+ <value>0</value>
</param>
<param>
- <key>taps</key>
- <value>firdes.root_raised_cosine(nfilts, nfilts,1.0/sps, 0.35, int(22*sps*nfilts))</value>
+ <key>stop</key>
+ <value>2</value>
</param>
<param>
- <key>filter_size</key>
- <value>nfilts</value>
+ <key>step</key>
+ <value>0.01</value>
</param>
<param>
- <key>init_phase</key>
- <value>nfilts/2</value>
+ <key>widget</key>
+ <value>counter_slider</value>
</param>
<param>
- <key>max_dev</key>
- <value>1.5</value>
+ <key>orient</key>
+ <value>Qt.Horizontal</value>
</param>
<param>
- <key>osps</key>
- <value>1</value>
+ <key>min_len</key>
+ <value>200</value>
+ </param>
+ <param>
+ <key>gui_hint</key>
+ <value></value>
</param>
<param>
<key>_coordinate</key>
- <value>(322, 231)</value>
+ <value>(150, 326)</value>
</param>
<param>
<key>_rotation</key>
@@ -446,46 +476,54 @@
</param>
</block>
<block>
- <key>digital_psk_mod</key>
+ <key>variable_qtgui_range</key>
<param>
<key>id</key>
- <value>digital_psk_mod_0</value>
+ <value>noise</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>constellation_points</key>
- <value>4</value>
+ <key>label</key>
+ <value>Noise</value>
</param>
<param>
- <key>mod_code</key>
- <value>"gray"</value>
+ <key>value</key>
+ <value>0.050</value>
</param>
<param>
- <key>differential</key>
- <value>True</value>
+ <key>start</key>
+ <value>0.0001</value>
</param>
<param>
- <key>samples_per_symbol</key>
- <value>sps</value>
+ <key>stop</key>
+ <value>2</value>
</param>
<param>
- <key>excess_bw</key>
- <value>0.35</value>
+ <key>step</key>
+ <value>0.01</value>
</param>
<param>
- <key>verbose</key>
- <value>False</value>
+ <key>widget</key>
+ <value>counter_slider</value>
</param>
<param>
- <key>log</key>
- <value>False</value>
+ <key>orient</key>
+ <value>Qt.Horizontal</value>
+ </param>
+ <param>
+ <key>min_len</key>
+ <value>200</value>
+ </param>
+ <param>
+ <key>gui_hint</key>
+ <value></value>
</param>
<param>
<key>_coordinate</key>
- <value>(846, 32)</value>
+ <value>(341, 341)</value>
</param>
<param>
<key>_rotation</key>
@@ -493,38 +531,58 @@
</param>
</block>
<block>
- <key>channels_channel_model</key>
+ <key>qtgui_const_sink_x</key>
<param>
<key>id</key>
- <value>channels_channel_model_0</value>
+ <value>qtgui_const_sink_x_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>noise_voltage</key>
- <value>noise</value>
+ <key>type</key>
+ <value>complex</value>
</param>
<param>
- <key>freq_offset</key>
- <value>0.0</value>
+ <key>name</key>
+ <value>QT GUI Plot</value>
</param>
<param>
- <key>epsilon</key>
- <value>1.0</value>
+ <key>size</key>
+ <value>1024</value>
</param>
<param>
- <key>taps</key>
- <value>cmath.exp(1j*noise)</value>
+ <key>ymin</key>
+ <value>-2</value>
</param>
<param>
- <key>seed</key>
- <value>0</value>
+ <key>ymax</key>
+ <value>2</value>
+ </param>
+ <param>
+ <key>xmin</key>
+ <value>-2</value>
+ </param>
+ <param>
+ <key>xmax</key>
+ <value>2</value>
+ </param>
+ <param>
+ <key>nconnections</key>
+ <value>2</value>
+ </param>
+ <param>
+ <key>update_time</key>
+ <value>0.10</value>
+ </param>
+ <param>
+ <key>gui_hint</key>
+ <value></value>
</param>
<param>
<key>_coordinate</key>
- <value>(80, 247)</value>
+ <value>(752, 196)</value>
</param>
<param>
<key>_rotation</key>
@@ -551,7 +609,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(641, 313)</value>
+ <value>(609, 282)</value>
</param>
<param>
<key>_rotation</key>
@@ -562,7 +620,7 @@
<key>gr_ctrlport_probe2_c</key>
<param>
<key>id</key>
- <value>probe2_c_0</value>
+ <value>phase_probe2</value>
</param>
<param>
<key>_enabled</key>
@@ -570,7 +628,7 @@
</param>
<param>
<key>name</key>
- <value>constellation</value>
+ <value>phase locked</value>
</param>
<param>
<key>desc</key>
@@ -582,7 +640,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(936, 396)</value>
+ <value>(781, 383)</value>
</param>
<param>
<key>_rotation</key>
@@ -590,33 +648,10 @@
</param>
</block>
<block>
- <key>ctrlport_monitor</key>
- <param>
- <key>id</key>
- <value>ctrlport_monitor_0</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>en</key>
- <value>True</value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(228, 9)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>0</value>
- </param>
- </block>
- <block>
- <key>gr_vector_source_x</key>
+ <key>gr_null_sink</key>
<param>
<key>id</key>
- <value>gr_vector_source_x_0</value>
+ <value>gr_null_sink_0</value>
</param>
<param>
<key>_enabled</key>
@@ -624,15 +659,7 @@
</param>
<param>
<key>type</key>
- <value>byte</value>
- </param>
- <param>
- <key>vector</key>
- <value>0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50</value>
- </param>
- <param>
- <key>repeat</key>
- <value>True</value>
+ <value>complex</value>
</param>
<param>
<key>vlen</key>
@@ -640,7 +667,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(234, 126)</value>
+ <value>(866, 343)</value>
</param>
<param>
<key>_rotation</key>
@@ -648,34 +675,30 @@
</param>
</block>
<block>
- <key>blocks_file_source</key>
+ <key>gr_ctrlport_probe2_c</key>
<param>
<key>id</key>
- <value>blocks_file_source_0</value>
+ <value>time_probe2</value>
</param>
<param>
<key>_enabled</key>
- <value>False</value>
- </param>
- <param>
- <key>file</key>
- <value>/dev/urandom</value>
+ <value>True</value>
</param>
<param>
- <key>type</key>
- <value>byte</value>
+ <key>name</key>
+ <value>time locked</value>
</param>
<param>
- <key>repeat</key>
- <value>True</value>
+ <key>desc</key>
+ <value>Constellation Points</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>len</key>
+ <value>1024</value>
</param>
<param>
<key>_coordinate</key>
- <value>(228, 56)</value>
+ <value>(518, 435)</value>
</param>
<param>
<key>_rotation</key>
@@ -683,34 +706,30 @@
</param>
</block>
<block>
- <key>blocks_packed_to_unpacked_xx</key>
+ <key>gr_ctrlport_probe2_c</key>
<param>
<key>id</key>
- <value>blocks_packed_to_unpacked_xx_0</value>
+ <value>received_probe2</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>byte</value>
- </param>
- <param>
- <key>bits_per_chunk</key>
- <value>8</value>
+ <key>name</key>
+ <value>received</value>
</param>
<param>
- <key>endianness</key>
- <value>gr.GR_MSB_FIRST</value>
+ <key>desc</key>
+ <value>Constellation Points</value>
</param>
<param>
- <key>num_ports</key>
- <value>1</value>
+ <key>len</key>
+ <value>1024</value>
</param>
<param>
<key>_coordinate</key>
- <value>(419, 56)</value>
+ <value>(368, 515)</value>
</param>
<param>
<key>_rotation</key>
@@ -718,30 +737,38 @@
</param>
</block>
<block>
- <key>blocks_throttle</key>
+ <key>channels_channel_model</key>
<param>
<key>id</key>
- <value>blocks_throttle_0</value>
+ <value>channels_channel_model_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>byte</value>
+ <key>noise_voltage</key>
+ <value>noise</value>
</param>
<param>
- <key>samples_per_second</key>
- <value>samp_rate</value>
+ <key>freq_offset</key>
+ <value>0.0</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>epsilon</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>taps</key>
+ <value>cmath.exp(1j*phase)</value>
+ </param>
+ <param>
+ <key>seed</key>
+ <value>0</value>
</param>
<param>
<key>_coordinate</key>
- <value>(623, 64)</value>
+ <value>(68, 211)</value>
</param>
<param>
<key>_rotation</key>
@@ -756,12 +783,6 @@
</connection>
<connection>
<source_block_id>digital_pfb_clock_sync_xxx_0</source_block_id>
- <sink_block_id>digital_costas_loop_cc_0</sink_block_id>
- <source_key>0</source_key>
- <sink_key>0</sink_key>
- </connection>
- <connection>
- <source_block_id>digital_pfb_clock_sync_xxx_0</source_block_id>
<sink_block_id>qtgui_const_sink_x_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
@@ -792,7 +813,7 @@
</connection>
<connection>
<source_block_id>digital_costas_loop_cc_0</source_block_id>
- <sink_block_id>probe2_c_0</sink_block_id>
+ <sink_block_id>phase_probe2</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
@@ -809,8 +830,20 @@
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_file_source_0</source_block_id>
- <sink_block_id>blocks_packed_to_unpacked_xx_0</sink_block_id>
+ <source_block_id>channels_channel_model_0</source_block_id>
+ <sink_block_id>received_probe2</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>digital_pfb_clock_sync_xxx_0</source_block_id>
+ <sink_block_id>time_probe2</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>digital_pfb_clock_sync_xxx_0</source_block_id>
+ <sink_block_id>digital_costas_loop_cc_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
diff --git a/gnuradio-core/src/lib/runtime/gr_block.cc b/gnuradio-core/src/lib/runtime/gr_block.cc
index cb38df27a8..8c8b85dc7e 100644
--- a/gnuradio-core/src/lib/runtime/gr_block.cc
+++ b/gnuradio-core/src/lib/runtime/gr_block.cc
@@ -330,6 +330,17 @@ gr_block::pc_noutput_items()
}
float
+gr_block::pc_noutput_items_avg()
+{
+ if(d_detail) {
+ return d_detail->pc_noutput_items_avg();
+ }
+ else {
+ return 0;
+ }
+}
+
+float
gr_block::pc_noutput_items_var()
{
if(d_detail) {
@@ -352,6 +363,17 @@ gr_block::pc_nproduced()
}
float
+gr_block::pc_nproduced_avg()
+{
+ if(d_detail) {
+ return d_detail->pc_nproduced_avg();
+ }
+ else {
+ return 0;
+ }
+}
+
+float
gr_block::pc_nproduced_var()
{
if(d_detail) {
@@ -374,6 +396,17 @@ gr_block::pc_input_buffers_full(int which)
}
float
+gr_block::pc_input_buffers_full_avg(int which)
+{
+ if(d_detail) {
+ return d_detail->pc_input_buffers_full_avg(static_cast<size_t>(which));
+ }
+ else {
+ return 0;
+ }
+}
+
+float
gr_block::pc_input_buffers_full_var(int which)
{
if(d_detail) {
@@ -396,6 +429,17 @@ gr_block::pc_input_buffers_full()
}
std::vector<float>
+gr_block::pc_input_buffers_full_avg()
+{
+ if(d_detail) {
+ return d_detail->pc_input_buffers_full_avg();
+ }
+ else {
+ return std::vector<float>(1,0);
+ }
+}
+
+std::vector<float>
gr_block::pc_input_buffers_full_var()
{
if(d_detail) {
@@ -418,6 +462,17 @@ gr_block::pc_output_buffers_full(int which)
}
float
+gr_block::pc_output_buffers_full_avg(int which)
+{
+ if(d_detail) {
+ return d_detail->pc_output_buffers_full_avg(static_cast<size_t>(which));
+ }
+ else {
+ return 0;
+ }
+}
+
+float
gr_block::pc_output_buffers_full_var(int which)
{
if(d_detail) {
@@ -440,6 +495,17 @@ gr_block::pc_output_buffers_full()
}
std::vector<float>
+gr_block::pc_output_buffers_full_avg()
+{
+ if(d_detail) {
+ return d_detail->pc_output_buffers_full_avg();
+ }
+ else {
+ return std::vector<float>(1,0);
+ }
+}
+
+std::vector<float>
gr_block::pc_output_buffers_full_var()
{
if(d_detail) {
@@ -462,6 +528,17 @@ gr_block::pc_work_time()
}
float
+gr_block::pc_work_time_avg()
+{
+ if(d_detail) {
+ return d_detail->pc_work_time_avg();
+ }
+ else {
+ return 0;
+ }
+}
+
+float
gr_block::pc_work_time_var()
{
if(d_detail) {
@@ -487,7 +564,14 @@ gr_block::setup_pc_rpc()
#ifdef GR_CTRLPORT
d_rpc_vars.push_back(
rpcbasic_sptr(new rpcbasic_register_get<gr_block, float>(
- alias(), "avg noutput_items", &gr_block::pc_noutput_items,
+ alias(), "noutput_items", &gr_block::pc_noutput_items,
+ pmt::mp(0), pmt::mp(32768), pmt::mp(0),
+ "", "noutput items", RPC_PRIVLVL_MIN,
+ DISPTIME | DISPOPTSTRIP)));
+
+ d_rpc_vars.push_back(
+ rpcbasic_sptr(new rpcbasic_register_get<gr_block, float>(
+ alias(), "avg noutput_items", &gr_block::pc_noutput_items_avg,
pmt::mp(0), pmt::mp(32768), pmt::mp(0),
"", "Average noutput items", RPC_PRIVLVL_MIN,
DISPTIME | DISPOPTSTRIP)));
@@ -501,7 +585,14 @@ gr_block::setup_pc_rpc()
d_rpc_vars.push_back(
rpcbasic_sptr(new rpcbasic_register_get<gr_block, float>(
- alias(), "avg nproduced", &gr_block::pc_nproduced,
+ alias(), "nproduced", &gr_block::pc_nproduced,
+ pmt::mp(0), pmt::mp(32768), pmt::mp(0),
+ "", "items produced", RPC_PRIVLVL_MIN,
+ DISPTIME | DISPOPTSTRIP)));
+
+ d_rpc_vars.push_back(
+ rpcbasic_sptr(new rpcbasic_register_get<gr_block, float>(
+ alias(), "avg nproduced", &gr_block::pc_nproduced_avg,
pmt::mp(0), pmt::mp(32768), pmt::mp(0),
"", "Average items produced", RPC_PRIVLVL_MIN,
DISPTIME | DISPOPTSTRIP)));
@@ -515,7 +606,14 @@ gr_block::setup_pc_rpc()
d_rpc_vars.push_back(
rpcbasic_sptr(new rpcbasic_register_get<gr_block, float>(
- alias(), "avg work time", &gr_block::pc_work_time,
+ alias(), "work time", &gr_block::pc_work_time,
+ pmt::mp(0), pmt::mp(1e9), pmt::mp(0),
+ "", "clock cycles in call to work", RPC_PRIVLVL_MIN,
+ DISPTIME | DISPOPTSTRIP)));
+
+ d_rpc_vars.push_back(
+ rpcbasic_sptr(new rpcbasic_register_get<gr_block, float>(
+ alias(), "avg work time", &gr_block::pc_work_time_avg,
pmt::mp(0), pmt::mp(1e9), pmt::mp(0),
"", "Average clock cycles in call to work", RPC_PRIVLVL_MIN,
DISPTIME | DISPOPTSTRIP)));
@@ -529,7 +627,14 @@ gr_block::setup_pc_rpc()
d_rpc_vars.push_back(
rpcbasic_sptr(new rpcbasic_register_get<gr_block, std::vector<float> >(
- alias(), "avg input \% full", &gr_block::pc_input_buffers_full,
+ alias(), "input \% full", &gr_block::pc_input_buffers_full,
+ pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
+ "", "how full input buffers are", RPC_PRIVLVL_MIN,
+ DISPTIME | DISPOPTSTRIP)));
+
+ d_rpc_vars.push_back(
+ rpcbasic_sptr(new rpcbasic_register_get<gr_block, std::vector<float> >(
+ alias(), "avg input \% full", &gr_block::pc_input_buffers_full_avg,
pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
"", "Average of how full input buffers are", RPC_PRIVLVL_MIN,
DISPTIME | DISPOPTSTRIP)));
@@ -543,7 +648,14 @@ gr_block::setup_pc_rpc()
d_rpc_vars.push_back(
rpcbasic_sptr(new rpcbasic_register_get<gr_block, std::vector<float> >(
- alias(), "avg output \% full", &gr_block::pc_output_buffers_full,
+ alias(), "output \% full", &gr_block::pc_output_buffers_full,
+ pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
+ "", "how full output buffers are", RPC_PRIVLVL_MIN,
+ DISPTIME | DISPOPTSTRIP)));
+
+ d_rpc_vars.push_back(
+ rpcbasic_sptr(new rpcbasic_register_get<gr_block, std::vector<float> >(
+ alias(), "avg output \% full", &gr_block::pc_output_buffers_full_avg,
pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
"", "Average of how full output buffers are", RPC_PRIVLVL_MIN,
DISPTIME | DISPOPTSTRIP)));
diff --git a/gnuradio-core/src/lib/runtime/gr_block.h b/gnuradio-core/src/lib/runtime/gr_block.h
index dd17ea2ca2..f13f54870d 100644
--- a/gnuradio-core/src/lib/runtime/gr_block.h
+++ b/gnuradio-core/src/lib/runtime/gr_block.h
@@ -379,72 +379,108 @@ class GR_CORE_API gr_block : public gr_basic_block {
// --------------- Performance counter functions -------------
/*!
- * \brief Gets average noutput_items performance counter.
+ * \brief Gets instantaneous noutput_items performance counter.
*/
float pc_noutput_items();
/*!
+ * \brief Gets average noutput_items performance counter.
+ */
+ float pc_noutput_items_avg();
+
+ /*!
* \brief Gets variance of noutput_items performance counter.
*/
float pc_noutput_items_var();
/*!
- * \brief Gets average num items produced performance counter.
+ * \brief Gets instantaneous num items produced performance counter.
*/
float pc_nproduced();
/*!
+ * \brief Gets average num items produced performance counter.
+ */
+ float pc_nproduced_avg();
+
+ /*!
* \brief Gets variance of num items produced performance counter.
*/
float pc_nproduced_var();
/*!
- * \brief Gets average fullness of \p which input buffer.
+ * \brief Gets instantaneous fullness of \p which input buffer.
*/
float pc_input_buffers_full(int which);
/*!
+ * \brief Gets average fullness of \p which input buffer.
+ */
+ float pc_input_buffers_full_avg(int which);
+
+ /*!
* \brief Gets variance of fullness of \p which input buffer.
*/
float pc_input_buffers_full_var(int which);
/*!
- * \brief Gets average fullness of all input buffers.
+ * \brief Gets instantaneous fullness of all input buffers.
*/
std::vector<float> pc_input_buffers_full();
/*!
+ * \brief Gets average fullness of all input buffers.
+ */
+ std::vector<float> pc_input_buffers_full_avg();
+
+ /*!
* \brief Gets variance of fullness of all input buffers.
*/
std::vector<float> pc_input_buffers_full_var();
/*!
- * \brief Gets average fullness of \p which input buffer.
+ * \brief Gets instantaneous fullness of \p which input buffer.
*/
float pc_output_buffers_full(int which);
/*!
+ * \brief Gets average fullness of \p which input buffer.
+ */
+ float pc_output_buffers_full_avg(int which);
+
+ /*!
* \brief Gets variance of fullness of \p which input buffer.
*/
float pc_output_buffers_full_var(int which);
/*!
- * \brief Gets average fullness of all output buffers.
+ * \brief Gets instantaneous fullness of all output buffers.
*/
std::vector<float> pc_output_buffers_full();
+
+ /*!
+ * \brief Gets average fullness of all output buffers.
+ */
+ std::vector<float> pc_output_buffers_full_avg();
+
/*!
* \brief Gets variance of fullness of all output buffers.
*/
std::vector<float> pc_output_buffers_full_var();
/*!
- * \brief Gets average clock cycles spent in work.
+ * \brief Gets instantaneous clock cycles spent in work.
*/
float pc_work_time();
/*!
* \brief Gets average clock cycles spent in work.
*/
+ float pc_work_time_avg();
+
+ /*!
+ * \brief Gets average clock cycles spent in work.
+ */
float pc_work_time_var();
/*!
diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.cc b/gnuradio-core/src/lib/runtime/gr_block_detail.cc
index c05b7b96a0..c85c0e9fba 100644
--- a/gnuradio-core/src/lib/runtime/gr_block_detail.cc
+++ b/gnuradio-core/src/lib/runtime/gr_block_detail.cc
@@ -41,14 +41,19 @@ gr_block_detail::gr_block_detail (unsigned int ninputs, unsigned int noutputs)
d_ninputs (ninputs), d_noutputs (noutputs),
d_input (ninputs), d_output (noutputs),
d_done (false),
+ d_ins_noutput_items(0),
d_avg_noutput_items(0),
d_var_noutput_items(0),
+ d_ins_nproduced(0),
d_avg_nproduced(0),
d_var_nproduced(0),
+ d_ins_input_buffers_full(ninputs, 0),
d_avg_input_buffers_full(ninputs, 0),
d_var_input_buffers_full(ninputs, 0),
+ d_ins_output_buffers_full(noutputs, 0),
d_avg_output_buffers_full(noutputs, 0),
d_var_output_buffers_full(noutputs, 0),
+ d_ins_work_time(0),
d_avg_work_time(0),
d_var_work_time(0),
d_pc_counter(0)
@@ -246,35 +251,43 @@ gr_block_detail::stop_perf_counters(int noutput_items, int nproduced)
gruel::high_res_timer_type diff = d_end_of_work - d_start_of_work;
if(d_pc_counter == 0) {
+ d_ins_work_time = diff;
d_avg_work_time = diff;
d_var_work_time = 0;
+ d_ins_nproduced = nproduced;
d_avg_nproduced = nproduced;
d_var_nproduced = 0;
+ d_ins_noutput_items = noutput_items;
d_avg_noutput_items = noutput_items;
d_var_noutput_items = 0;
for(size_t i=0; i < d_input.size(); i++) {
float pfull = static_cast<float>(d_input[i]->items_available()) /
static_cast<float>(d_input[i]->max_possible_items_available());
+ d_ins_input_buffers_full[i] = pfull;
d_avg_input_buffers_full[i] = pfull;
d_var_input_buffers_full[i] = 0;
}
for(size_t i=0; i < d_output.size(); i++) {
float pfull = 1.0f - static_cast<float>(d_output[i]->space_available()) /
static_cast<float>(d_output[i]->bufsize());
+ d_ins_output_buffers_full[i] = pfull;
d_avg_output_buffers_full[i] = pfull;
d_var_output_buffers_full[i] = 0;
}
}
else {
float d = diff - d_avg_work_time;
+ d_ins_work_time = diff;
d_avg_work_time = d_avg_work_time + d/d_pc_counter;
d_var_work_time = d_var_work_time + d*d;
d = nproduced - d_avg_nproduced;
+ d_ins_nproduced = nproduced;
d_avg_nproduced = d_avg_nproduced + d/d_pc_counter;
d_var_nproduced = d_var_nproduced + d*d;
d = noutput_items - d_avg_noutput_items;
+ d_ins_noutput_items = noutput_items;
d_avg_noutput_items = d_avg_noutput_items + d/d_pc_counter;
d_var_noutput_items = d_var_noutput_items + d*d;
@@ -283,6 +296,7 @@ gr_block_detail::stop_perf_counters(int noutput_items, int nproduced)
static_cast<float>(d_input[i]->max_possible_items_available());
d = pfull - d_avg_input_buffers_full[i];
+ d_ins_input_buffers_full[i] = pfull;
d_avg_input_buffers_full[i] = d_avg_input_buffers_full[i] + d/d_pc_counter;
d_var_input_buffers_full[i] = d_var_input_buffers_full[i] + d*d;
}
@@ -292,6 +306,7 @@ gr_block_detail::stop_perf_counters(int noutput_items, int nproduced)
static_cast<float>(d_output[i]->bufsize());
d = pfull - d_avg_output_buffers_full[i];
+ d_ins_output_buffers_full[i] = pfull;
d_avg_output_buffers_full[i] = d_avg_output_buffers_full[i] + d/d_pc_counter;
d_var_output_buffers_full[i] = d_var_output_buffers_full[i] + d*d;
}
@@ -309,18 +324,66 @@ gr_block_detail::reset_perf_counters()
float
gr_block_detail::pc_noutput_items()
{
- return d_avg_noutput_items;
+ return d_ins_noutput_items;
}
float
gr_block_detail::pc_nproduced()
{
- return d_avg_nproduced;
+ return d_ins_nproduced;
}
float
gr_block_detail::pc_input_buffers_full(size_t which)
{
+ if(which < d_ins_input_buffers_full.size())
+ return d_ins_input_buffers_full[which];
+ else
+ return 0;
+}
+
+std::vector<float>
+gr_block_detail::pc_input_buffers_full()
+{
+ return d_ins_input_buffers_full;
+}
+
+float
+gr_block_detail::pc_output_buffers_full(size_t which)
+{
+ if(which < d_ins_output_buffers_full.size())
+ return d_ins_output_buffers_full[which];
+ else
+ return 0;
+}
+
+std::vector<float>
+gr_block_detail::pc_output_buffers_full()
+{
+ return d_ins_output_buffers_full;
+}
+
+float
+gr_block_detail::pc_work_time()
+{
+ return d_ins_work_time;
+}
+
+float
+gr_block_detail::pc_noutput_items_avg()
+{
+ return d_avg_noutput_items;
+}
+
+float
+gr_block_detail::pc_nproduced_avg()
+{
+ return d_avg_nproduced;
+}
+
+float
+gr_block_detail::pc_input_buffers_full_avg(size_t which)
+{
if(which < d_avg_input_buffers_full.size())
return d_avg_input_buffers_full[which];
else
@@ -328,13 +391,13 @@ gr_block_detail::pc_input_buffers_full(size_t which)
}
std::vector<float>
-gr_block_detail::pc_input_buffers_full()
+gr_block_detail::pc_input_buffers_full_avg()
{
return d_avg_input_buffers_full;
}
float
-gr_block_detail::pc_output_buffers_full(size_t which)
+gr_block_detail::pc_output_buffers_full_avg(size_t which)
{
if(which < d_avg_output_buffers_full.size())
return d_avg_output_buffers_full[which];
@@ -343,13 +406,13 @@ gr_block_detail::pc_output_buffers_full(size_t which)
}
std::vector<float>
-gr_block_detail::pc_output_buffers_full()
+gr_block_detail::pc_output_buffers_full_avg()
{
return d_avg_output_buffers_full;
}
float
-gr_block_detail::pc_work_time()
+gr_block_detail::pc_work_time_avg()
{
return d_avg_work_time;
}
diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.h b/gnuradio-core/src/lib/runtime/gr_block_detail.h
index 32a01e763a..8a5a08bcf3 100644
--- a/gnuradio-core/src/lib/runtime/gr_block_detail.h
+++ b/gnuradio-core/src/lib/runtime/gr_block_detail.h
@@ -184,6 +184,14 @@ class GR_CORE_API gr_block_detail {
std::vector<float> pc_output_buffers_full();
float pc_work_time();
+ float pc_noutput_items_avg();
+ float pc_nproduced_avg();
+ float pc_input_buffers_full_avg(size_t which);
+ std::vector<float> pc_input_buffers_full_avg();
+ float pc_output_buffers_full_avg(size_t which);
+ std::vector<float> pc_output_buffers_full_avg();
+ float pc_work_time_avg();
+
float pc_noutput_items_var();
float pc_nproduced_var();
float pc_input_buffers_full_var(size_t which);
@@ -205,15 +213,20 @@ class GR_CORE_API gr_block_detail {
bool d_done;
// Performance counters
+ float d_ins_noutput_items;
float d_avg_noutput_items;
float d_var_noutput_items;
+ float d_ins_nproduced;
float d_avg_nproduced;
float d_var_nproduced;
+ std::vector<float> d_ins_input_buffers_full;
std::vector<float> d_avg_input_buffers_full;
std::vector<float> d_var_input_buffers_full;
+ std::vector<float> d_ins_output_buffers_full;
std::vector<float> d_avg_output_buffers_full;
std::vector<float> d_var_output_buffers_full;
gruel::high_res_timer_type d_start_of_work, d_end_of_work;
+ float d_ins_work_time;
float d_avg_work_time;
float d_var_work_time;
float d_pc_counter;
diff --git a/gnuradio-core/src/python/gnuradio/ctrlport/gr-perf-monitorx b/gnuradio-core/src/python/gnuradio/ctrlport/gr-perf-monitorx
new file mode 100755
index 0000000000..f70e7d7cff
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/ctrlport/gr-perf-monitorx
@@ -0,0 +1,710 @@
+#!/usr/bin/env python
+#
+# Copyright 2012-2013 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.
+#
+
+import random,math,operator
+import networkx as nx;
+import matplotlib.pyplot as plt
+
+from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
+from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar
+from matplotlib.figure import Figure
+
+from gnuradio import gr, ctrlport
+
+from PyQt4 import QtCore,Qt,Qwt5
+import PyQt4.QtGui as QtGui
+import sys, time, re, pprint
+import itertools
+import scipy
+from scipy import spatial
+
+import Ice
+from gnuradio.ctrlport.IceRadioClient import *
+from gnuradio.ctrlport.GrDataPlotter import *
+from gnuradio.ctrlport import GNURadio
+
+class MAINWindow(QtGui.QMainWindow):
+ def minimumSizeHint(self):
+ return QtGui.QSize(800,600)
+
+ def __init__(self, radio, port, interface):
+
+ super(MAINWindow, self).__init__()
+ self.conns = []
+ self.plots = []
+ self.knobprops = []
+ self.interface = interface
+
+ self.mdiArea = QtGui.QMdiArea()
+ self.mdiArea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
+ self.mdiArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
+ self.setCentralWidget(self.mdiArea)
+
+ self.mdiArea.subWindowActivated.connect(self.updateMenus)
+ self.windowMapper = QtCore.QSignalMapper(self)
+ self.windowMapper.mapped[QtGui.QWidget].connect(self.setActiveSubWindow)
+
+ self.createActions()
+ self.createMenus()
+ self.createToolBars()
+ self.createStatusBar()
+ self.updateMenus()
+
+ self.setWindowTitle("GNU Radio Performance Monitor")
+ self.setUnifiedTitleAndToolBarOnMac(True)
+
+ self.newCon(radio, port)
+ icon = QtGui.QIcon(ctrlport.__path__[0] + "/icon.png" )
+ self.setWindowIcon(icon)
+
+
+ def newSubWindow(self, window, title):
+ child = window;
+ child.setWindowTitle(title)
+ self.mdiArea.addSubWindow(child)
+ self.conns.append(child)
+ child.show();
+ self.mdiArea.currentSubWindow().showMaximized()
+
+
+ def newCon(self, radio=None, port=None):
+ child = MForm(radio, port, len(self.conns), self)
+ if(child.radio is not None):
+ child.setWindowTitle(str(child.radio))
+# horizbar = QtGui.QScrollArea()
+# horizbar.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
+# horizbar.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
+# horizbar.setWidget(child)
+# self.mdiArea.addSubWindow(horizbar)
+ self.mdiArea.addSubWindow(child)
+ self.mdiArea.currentSubWindow().showMaximized()
+
+ self.conns.append(child)
+ self.plots.append([])
+
+ def update(self, knobs, uid):
+ #sys.stderr.write("KNOB KEYS: {0}\n".format(knobs.keys()))
+ for plot in self.plots[uid]:
+ data = knobs[plot.name()].value
+ plot.update(data)
+ plot.stop()
+ plot.wait()
+ plot.start()
+
+ def setActiveSubWindow(self, window):
+ if window:
+ self.mdiArea.setActiveSubWindow(window)
+
+
+ def createActions(self):
+ self.newConAct = QtGui.QAction("&New Connection",
+ self, shortcut=QtGui.QKeySequence.New,
+ statusTip="Create a new file", triggered=self.newCon)
+
+ self.exitAct = QtGui.QAction("E&xit", self, shortcut="Ctrl+Q",
+ statusTip="Exit the application",
+ triggered=QtGui.qApp.closeAllWindows)
+
+ self.closeAct = QtGui.QAction("Cl&ose", self, shortcut="Ctrl+F4",
+ statusTip="Close the active window",
+ triggered=self.mdiArea.closeActiveSubWindow)
+
+ self.closeAllAct = QtGui.QAction("Close &All", self,
+ statusTip="Close all the windows",
+ triggered=self.mdiArea.closeAllSubWindows)
+
+
+ qks = QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_T);
+ self.tileAct = QtGui.QAction("&Tile", self,
+ statusTip="Tile the windows",
+ triggered=self.mdiArea.tileSubWindows,
+ shortcut=qks)
+
+ qks = QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_C);
+ self.cascadeAct = QtGui.QAction("&Cascade", self,
+ statusTip="Cascade the windows", shortcut=qks,
+ triggered=self.mdiArea.cascadeSubWindows)
+
+ self.nextAct = QtGui.QAction("Ne&xt", self,
+ shortcut=QtGui.QKeySequence.NextChild,
+ statusTip="Move the focus to the next window",
+ triggered=self.mdiArea.activateNextSubWindow)
+
+ self.previousAct = QtGui.QAction("Pre&vious", self,
+ shortcut=QtGui.QKeySequence.PreviousChild,
+ statusTip="Move the focus to the previous window",
+ triggered=self.mdiArea.activatePreviousSubWindow)
+
+ self.separatorAct = QtGui.QAction(self)
+ self.separatorAct.setSeparator(True)
+
+ self.aboutAct = QtGui.QAction("&About", self,
+ statusTip="Show the application's About box",
+ triggered=self.about)
+
+ self.aboutQtAct = QtGui.QAction("About &Qt", self,
+ statusTip="Show the Qt library's About box",
+ triggered=QtGui.qApp.aboutQt)
+
+ def createMenus(self):
+ self.fileMenu = self.menuBar().addMenu("&File")
+ self.fileMenu.addAction(self.newConAct)
+ self.fileMenu.addSeparator()
+ self.fileMenu.addAction(self.exitAct)
+
+ self.windowMenu = self.menuBar().addMenu("&Window")
+ self.updateWindowMenu()
+ self.windowMenu.aboutToShow.connect(self.updateWindowMenu)
+
+ self.menuBar().addSeparator()
+
+ self.helpMenu = self.menuBar().addMenu("&Help")
+ self.helpMenu.addAction(self.aboutAct)
+ self.helpMenu.addAction(self.aboutQtAct)
+
+ def createToolBars(self):
+ self.fileToolBar = self.addToolBar("File")
+ self.fileToolBar.addAction(self.newConAct)
+
+ self.fileToolBar = self.addToolBar("Window")
+ self.fileToolBar.addAction(self.tileAct)
+ self.fileToolBar.addAction(self.cascadeAct)
+
+ def createStatusBar(self):
+ self.statusBar().showMessage("Ready")
+
+
+ def activeMdiChild(self):
+ activeSubWindow = self.mdiArea.activeSubWindow()
+ if activeSubWindow:
+ return activeSubWindow.widget()
+ return None
+
+ def updateMenus(self):
+ hasMdiChild = (self.activeMdiChild() is not None)
+ self.closeAct.setEnabled(hasMdiChild)
+ self.closeAllAct.setEnabled(hasMdiChild)
+ self.tileAct.setEnabled(hasMdiChild)
+ self.cascadeAct.setEnabled(hasMdiChild)
+ self.nextAct.setEnabled(hasMdiChild)
+ self.previousAct.setEnabled(hasMdiChild)
+ self.separatorAct.setVisible(hasMdiChild)
+
+ def updateWindowMenu(self):
+ self.windowMenu.clear()
+ self.windowMenu.addAction(self.closeAct)
+ self.windowMenu.addAction(self.closeAllAct)
+ self.windowMenu.addSeparator()
+ self.windowMenu.addAction(self.tileAct)
+ self.windowMenu.addAction(self.cascadeAct)
+ self.windowMenu.addSeparator()
+ self.windowMenu.addAction(self.nextAct)
+ self.windowMenu.addAction(self.previousAct)
+ self.windowMenu.addAction(self.separatorAct)
+
+ def about(self):
+ about_info = \
+'''Copyright 2012 Free Software Foundation, Inc.\n
+This program is part of GNU Radio.\n
+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.\n
+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.\n
+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.'''
+
+ QtGui.QMessageBox.about(None, "gr-ctrlport-monitor", about_info)
+
+
+class ConInfoDialog(QtGui.QDialog):
+ def __init__(self, parent=None):
+ super(ConInfoDialog, self).__init__(parent)
+
+ self.gridLayout = QtGui.QGridLayout(self)
+
+
+ self.host = QtGui.QLineEdit(self);
+ self.port = QtGui.QLineEdit(self);
+ self.host.setText("localhost");
+ self.port.setText("43243");
+
+ self.buttonBox = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok |
+ QtGui.QDialogButtonBox.Cancel)
+
+ self.gridLayout.addWidget(self.host);
+ self.gridLayout.addWidget(self.port);
+ self.gridLayout.addWidget(self.buttonBox);
+
+ self.buttonBox.accepted.connect(self.accept)
+ self.buttonBox.rejected.connect(self.reject)
+
+
+ def accept(self):
+ self.done(1);
+
+ def reject(self):
+ self.done(0);
+
+
+class DataTable(QtGui.QWidget):
+ def update(self):
+ print "update"
+
+ def __init__(self, radio, G):
+ QtGui.QWidget.__init__( self)
+
+ self.layout = QtGui.QVBoxLayout(self);
+ self.hlayout = QtGui.QHBoxLayout();
+ self.layout.addLayout(self.hlayout);
+
+ self.G = G;
+ self.radio = radio;
+
+ # Create a combobox to set the type of statistic we want.
+ self._statistic = "Instantaneous"
+ self._statistics_table = {"Instantaneous": "",
+ "Average": "avg ",
+ "Variance": "var "}
+ self.stattype = QtGui.QComboBox()
+ self.stattype.addItem("Instantaneous")
+ self.stattype.addItem("Average")
+ self.stattype.addItem("Variance")
+ self.stattype.setMaximumWidth(200)
+ self.hlayout.addWidget(self.stattype);
+ self.stattype.currentIndexChanged.connect(self.stat_changed)
+
+ # Create a checkbox to toggle sorting of graphs
+ self._sort = False
+ self.checksort = QtGui.QCheckBox("Sort")
+ self.checksort.setCheckState(self._sort)
+ self.hlayout.addWidget(self.checksort);
+ self.checksort.stateChanged.connect(self.checksort_changed)
+
+ # set up table
+ self.perfTable = Qt.QTableWidget();
+ self.perfTable.setColumnCount(2)
+ self.perfTable.verticalHeader().hide();
+ self.perfTable.setHorizontalHeaderLabels( ["Block Name", "Percent Runtime"] );
+ self.perfTable.horizontalHeader().setStretchLastSection(True);
+ self.perfTable.setSortingEnabled(True)
+ nodes = self.G.nodes(data=True)
+
+ # set up plot
+ self.f = plt.figure(figsize=(10,8), dpi=90)
+ self.sp = self.f.add_subplot(111);
+ self.sp.autoscale_view(True,True,True);
+ self.sp.set_autoscale_on(True)
+ self.canvas = FigureCanvas(self.f)
+
+ # set up tabs
+ self.tabber = QtGui.QTabWidget();
+ self.layout.addWidget(self.tabber);
+ self.tabber.addTab(self.perfTable,"Table View");
+ self.tabber.addTab(self.canvas, "Graph View");
+
+ # set up timer
+ self.timer = QtCore.QTimer()
+ self.connect(self.timer, QtCore.SIGNAL('timeout()'), self.update)
+ self.timer.start(500)
+
+ for i in range(0,len(nodes)):
+ self.perfTable.setItem(
+ i,0,
+ Qt.QTableWidgetItem(nodes[i][0]))
+
+ def table_update(self,data):
+ for k in data.keys():
+ weight = data[k]
+ existing = self.perfTable.findItems(str(k),QtCore.Qt.MatchFixedString)
+ if(len(existing) == 0):
+ i = self.perfTable.rowCount();
+ self.perfTable.setRowCount( i+1)
+ self.perfTable.setItem( i,0, Qt.QTableWidgetItem(str(k)))
+ self.perfTable.setItem( i,1, Qt.QTableWidgetItem(str(weight)))
+ else:
+ self.perfTable.setItem( self.perfTable.row(existing[0]),1, Qt.QTableWidgetItem(str(weight)))
+
+ def stat_changed(self, index):
+ self._statistic = str(self.stattype.currentText())
+
+ def checksort_changed(self, state):
+ self._sort = state > 0
+
+class DataTableBuffers(DataTable):
+ def __init__(self, radio, G):
+ DataTable.__init__(self,radio,G)
+ self.perfTable.setHorizontalHeaderLabels( ["Block Name", "Percent Buffer Full"] );
+
+ def update(self):
+ nodes = self.G.nodes();
+
+ # get buffer fullness for all blocks
+ kl = map(lambda x: "%s::%soutput %% full" % \
+ (x, self._statistics_table[self._statistic]),
+ nodes);
+ buf_knobs = self.radio.get(kl)
+
+ # strip values out of ctrlport response
+ buffer_fullness = dict(zip(
+ map(lambda x: x.split("::")[0], buf_knobs.keys()),
+ map(lambda x: x.value, buf_knobs.values())))
+
+ blockport_fullness = {}
+ for blk in buffer_fullness:
+ for port in range(0,len(buffer_fullness[blk])):
+ blockport_fullness["%s:%d"%(blk,port)] = buffer_fullness[blk][port];
+
+ self.table_update(blockport_fullness);
+
+ if(self._sort):
+ sorted_fullness = sorted(blockport_fullness.iteritems(), key=operator.itemgetter(1))
+ else:
+ sorted_fullness = blockport_fullness.items()
+
+ self.sp.clear();
+ plt.figure(self.f.number)
+ plt.subplot(111);
+ self.sp.bar( range(0,len(sorted_fullness)), map(lambda x: x[1], sorted_fullness))
+ self.sp.set_ylabel("% Buffers Full");
+ self.sp.set_xticks( map(lambda x: x+0.5, range(0,len(sorted_fullness))))
+ self.sp.set_xticklabels( map(lambda x: " " + x, map(lambda x: x[0], sorted_fullness)),
+ rotation="vertical", verticalalignment="bottom" )
+ self.canvas.draw();
+ self.canvas.show();
+
+class DataTableRuntimes(DataTable):
+ def __init__(self, radio, G):
+ DataTable.__init__(self,radio,G)
+ #self.perfTable.setRowCount(len( self.G.nodes() ))
+
+ def update(self):
+ nodes = self.G.nodes();
+
+ # get work time for all blocks
+ kl = map(lambda x: "%s::%swork time" % \
+ (x, self._statistics_table[self._statistic]),
+ nodes);
+ wrk_knobs = self.radio.get(kl)
+
+ # strip values out of ctrlport response
+ total_work = sum(map(lambda x: x.value, wrk_knobs.values()))
+ work_times = dict(zip(
+ map(lambda x: x.split("::")[0], wrk_knobs.keys()),
+ map(lambda x: x.value/total_work, wrk_knobs.values())))
+
+ # update table view
+ self.table_update(work_times)
+
+ if(self._sort):
+ sorted_work = sorted(work_times.iteritems(), key=operator.itemgetter(1))
+ else:
+ sorted_work = work_times.items()
+
+ self.sp.clear();
+ plt.figure(self.f.number)
+ plt.subplot(111);
+ self.sp.bar( range(0,len(sorted_work)), map(lambda x: x[1], sorted_work) )
+ self.sp.set_ylabel("% Runtime");
+ self.sp.set_xticks( map(lambda x: x+0.5, range(0,len(sorted_work))))
+ self.sp.set_xticklabels( map(lambda x: " " + x[0], sorted_work), rotation="vertical", verticalalignment="bottom" )
+
+ self.canvas.draw();
+ self.canvas.show();
+
+class MForm(QtGui.QWidget):
+ def update(self):
+ try:
+
+ nodes = self.G.nodes();
+
+ # get current buffer depths of all output buffers
+ kl = map(lambda x: "%s::%soutput %% full" % \
+ (x, self._statistics_table[self._statistic]),
+ nodes);
+
+ st = time.time()
+ buf_knobs = self.radio.get(kl)
+ td1 = time.time() - st;
+
+ # strip values out of ctrlport response
+ buf_vals = dict(zip(
+ map(lambda x: x.split("::")[0], buf_knobs.keys()),
+ map(lambda x: x.value, buf_knobs.values())))
+
+ # get work time for all blocks
+ kl = map(lambda x: "%s::%swork time" % \
+ (x, self._statistics_table[self._statistic]),
+ nodes);
+ st = time.time()
+ wrk_knobs = self.radio.get(kl)
+ td2 = time.time() - st;
+
+ # strip values out of ctrlport response
+ total_work = sum(map(lambda x: x.value, wrk_knobs.values()))
+ work_times = dict(zip(
+ map(lambda x: x.split("::")[0], wrk_knobs.keys()),
+ map(lambda x: x.value/total_work, wrk_knobs.values())))
+
+ for n in nodes:
+ # ne is the list of edges away from this node!
+ ne = self.G.edges([n],True);
+ for e in ne: # iterate over edges from this block
+ # get the right output buffer/port weight for each edge
+ sourceport = e[2]["sourceport"];
+ newweight = buf_vals[n][sourceport]
+ e[2]["weight"] = newweight;
+
+ # set updated weights
+ self.node_weights = map(lambda x: 20+2000*work_times[x], nodes);
+ self.edge_weights = map(lambda x: 100.0*x[2]["weight"], self.G.edges(data=True));
+
+ # draw graph updates
+ self.updateGraph();
+
+ latency = td1 + td2;
+ self.parent.statusBar().showMessage("Current GNU Radio Control Port Query Latency: %f ms"%\
+ (latency*1000))
+
+ except Exception, e:
+ sys.stderr.write("ctrlport-monitor: radio.get threw exception ({0}).\n".format(e))
+ if(type(self.parent) is MAINWindow):
+ # Find window of connection
+ remove = []
+ for p in self.parent.mdiArea.subWindowList():
+ if self.parent.conns[self.uid] == p.widget():
+ remove.append(p)
+
+ # Remove subwindows for connection and plots
+ for r in remove:
+ self.parent.mdiArea.removeSubWindow(r)
+
+ # Clean up self
+ self.close()
+ else:
+ sys.exit(1)
+ return
+
+ def rtt(self):
+ self.parent.newSubWindow( DataTableRuntimes(self.radio, self.G), "Runtime Table" );
+
+ def bpt(self):
+ self.parent.newSubWindow( DataTableBuffers(self.radio, self.G), "Buffers Table" );
+
+ def stat_changed(self, index):
+ self._statistic = str(self.stattype.currentText())
+
+ def __init__(self, radio=None, port=None, uid=0, parent=None):
+
+ super(MForm, self).__init__()
+
+ if(radio == None or port == None):
+ askinfo = ConInfoDialog(self);
+ if askinfo.exec_():
+ host = str(askinfo.host.text());
+ port = str(askinfo.port.text());
+ radio = parent.interface.getRadio(host, port)
+ else:
+ self.radio = None
+ return
+
+
+ self.uid = uid
+ self.parent = parent
+
+ self.layoutTop = QtGui.QVBoxLayout(self)
+ self.ctlBox = QtGui.QHBoxLayout();
+ self.layout = QtGui.QHBoxLayout()
+
+ self.layoutTop.addLayout(self.ctlBox);
+ self.layoutTop.addLayout(self.layout);
+
+ self.rttAct = QtGui.QAction("Runtime Table",
+ self, statusTip="Runtime Table", triggered=self.rtt)
+ self.rttBut = Qt.QToolButton()
+ self.rttBut.setDefaultAction(self.rttAct);
+ self.ctlBox.addWidget(self.rttBut);
+
+ self.bptAct = QtGui.QAction("Buffer Table",
+ self, statusTip="Buffer Table", triggered=self.bpt)
+ self.bptBut = Qt.QToolButton()
+ self.bptBut.setDefaultAction(self.bptAct);
+ self.ctlBox.addWidget(self.bptBut);
+
+ self._statistic = "Instantaneous"
+ self._statistics_table = {"Instantaneous": "",
+ "Average": "avg ",
+ "Variance": "var "}
+ self.stattype = QtGui.QComboBox()
+ self.stattype.addItem("Instantaneous")
+ self.stattype.addItem("Average")
+ self.stattype.addItem("Variance")
+ self.stattype.setMaximumWidth(200)
+ self.ctlBox.addWidget(self.stattype);
+ self.stattype.currentIndexChanged.connect(self.stat_changed)
+
+# self.setLayout(self.layout);
+
+ self.radio = radio
+ self.knobprops = self.radio.properties([])
+ self.parent.knobprops.append(self.knobprops)
+
+ self.timer = QtCore.QTimer()
+ self.constupdatediv = 0
+ self.tableupdatediv = 0
+ plotsize=250
+
+
+ # Set up the graph of blocks
+ input_name = lambda x: x+"::avg input % full"
+ output_name = lambda x: x+"::avg output % full"
+ wtime_name = lambda x: x+"::avg work time"
+ nout_name = lambda x: x+"::avg noutput_items"
+ nprod_name = lambda x: x+"::avg nproduced"
+
+ tmplist = []
+ knobs = self.radio.get([])
+ edgelist = None
+ for k in knobs:
+ propname = k.split("::")
+ blockname = propname[0]
+ keyname = propname[1]
+ if(keyname == "edge list"):
+ edgelist = knobs[k].value
+ elif(blockname not in tmplist):
+ # only take gr_blocks (no hier_block2)
+ if(knobs.has_key(input_name(blockname))):
+ tmplist.append(blockname)
+
+ if not edgelist:
+ sys.stderr.write("Could not find list of edges from flowgraph. " + \
+ "Make sure the option 'edges_list' is enabled " + \
+ "in the ControlPort configuration.\n\n")
+ sys.exit(1)
+
+ edges = edgelist.split("\n")[0:-1]
+ edgepairs = [];
+ for e in edges:
+ _e = e.split("->")
+ edgepairs.append( (_e[0].split(":")[0], _e[1].split(":")[0],
+ {"sourceport":int(_e[0].split(":")[1])}) );
+
+ self.G = nx.MultiDiGraph();
+ self.G.add_edges_from(edgepairs);
+
+ n_edges = self.G.edges(data=True);
+ for e in n_edges:
+ e[2]["weight"] = 5+random.random()*10;
+
+ self.G.clear();
+ self.G.add_edges_from(n_edges);
+
+
+ self.f = plt.figure(figsize=(10,8), dpi=90)
+ self.sp = self.f.add_subplot(111);
+ self.sp.autoscale_view(True,True,True);
+ self.sp.set_autoscale_on(True)
+
+ self.canvas = FigureCanvas(self.f)
+ self.layout.addWidget(self.canvas);
+
+ self.pos = nx.graphviz_layout(self.G);
+ #self.pos = nx.pygraphviz_layout(self.G);
+ #self.pos = nx.spectral_layout(self.G);
+ #self.pos = nx.circular_layout(self.G);
+ #self.pos = nx.shell_layout(self.G);
+ #self.pos = nx.spring_layout(self.G);
+
+ # generate weights and plot
+ self.update();
+
+ # set up timer
+ self.timer = QtCore.QTimer()
+ self.connect(self.timer, QtCore.SIGNAL('timeout()'), self.update)
+ self.timer.start(1000)
+
+ # Set up mouse callback functions to move blocks around.
+ self._grabbed = False
+ self._current_block = ''
+ self.f.canvas.mpl_connect('button_press_event',
+ self.button_press)
+ self.f.canvas.mpl_connect('motion_notify_event',
+ self.mouse_move)
+ self.f.canvas.mpl_connect('button_release_event',
+ self.button_release)
+
+ def button_press(self, event):
+ x, y = event.xdata, event.ydata
+ thrsh = 100
+
+ if(x is not None and y is not None):
+ nearby = map(lambda z: spatial.distance.euclidean((x,y), z), self.pos.values())
+ i = nearby.index(min(nearby))
+ if(abs(self.pos.values()[i][0] - x) < thrsh and
+ abs(self.pos.values()[i][1]-y) < thrsh):
+ self._current_block = self.pos.keys()[i]
+ #print "MOVING BLOCK: ", self._current_block
+ #print "CUR POS: ", self.pos.values()[i]
+ self._grabbed = True
+
+ def mouse_move(self, event):
+ if self._grabbed:
+ x, y = event.xdata, event.ydata
+ if(x is not None and y is not None):
+ #print "NEW POS: ", (x,y)
+ self.pos[self._current_block] = (x,y)
+ self.updateGraph();
+
+ def button_release(self, event):
+ self._grabbed = False
+
+
+ def openMenu(self, pos):
+ index = self.table.treeWidget.selectedIndexes()
+ item = self.table.treeWidget.itemFromIndex(index[0])
+ itemname = str(item.text(0))
+ self.parent.propertiesMenu(itemname, self.radio, self.uid)
+
+ def updateGraph(self):
+
+ self.canvas.updateGeometry()
+ self.sp.clear();
+ plt.figure(self.f.number)
+ plt.subplot(111);
+ nx.draw(self.G, self.pos,
+ edge_color=self.edge_weights,
+ node_color='#A0CBE2',
+ width=map(lambda x: 3+math.log(x), self.edge_weights),
+ node_shape="s",
+ node_size=self.node_weights,
+ #edge_cmap=plt.cm.Blues,
+ edge_cmap=plt.cm.Reds,
+ ax=self.sp,
+ arrows=False
+ )
+ nx.draw_networkx_labels(self.G, self.pos,
+ font_size=12)
+
+ self.canvas.draw();
+ self.canvas.show();
+
+class MyClient(IceRadioClient):
+ def __init__(self):
+ IceRadioClient.__init__(self, MAINWindow)
+
+sys.exit(MyClient().main(sys.argv))
diff --git a/gr-blocks/grc/blocks_probe_signal_vx.xml b/gr-blocks/grc/blocks_probe_signal_vx.xml
index f8836f05c2..f4e945ab0d 100644
--- a/gr-blocks/grc/blocks_probe_signal_vx.xml
+++ b/gr-blocks/grc/blocks_probe_signal_vx.xml
@@ -45,9 +45,11 @@
<value>1</value>
<type>int</type>
</param>
+ <check>$vlen &gt; 0</check>
<sink>
<name>in</name>
<type>$type</type>
+ <vlen>$vlen</vlen>
</sink>
<doc>
Available functions to probe: level()