diff options
-rw-r--r-- | gnuradio-core/src/examples/ctrlport/comparing_resamplers.grc | 390 | ||||
-rw-r--r-- | gnuradio-core/src/examples/ctrlport/pfb_sync_test-qt.grc | 521 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/gr_block.cc | 122 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/gr_block.h | 50 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/gr_block_detail.cc | 75 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/gr_block_detail.h | 13 | ||||
-rwxr-xr-x | gnuradio-core/src/python/gnuradio/ctrlport/gr-perf-monitorx | 710 | ||||
-rw-r--r-- | gr-blocks/grc/blocks_probe_signal_vx.xml | 2 |
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 > 0</check> <sink> <name>in</name> <type>$type</type> + <vlen>$vlen</vlen> </sink> <doc> Available functions to probe: level() |