diff options
-rw-r--r-- | gnuradio-runtime/lib/block.cc | 5 | ||||
-rw-r--r-- | gnuradio-runtime/lib/controlport/rpcpmtconverters_ice.cc | 17 | ||||
-rw-r--r-- | gnuradio-runtime/lib/top_block.cc | 16 | ||||
-rwxr-xr-x | gnuradio-runtime/python/gnuradio/ctrlport/gr-perf-monitorx | 87 | ||||
-rw-r--r-- | gnuradio-runtime/python/gnuradio/ctrlport/icon.png | bin | 1532 -> 4377 bytes |
5 files changed, 97 insertions, 28 deletions
diff --git a/gnuradio-runtime/lib/block.cc b/gnuradio-runtime/lib/block.cc index 7a1364def9..2e629d058a 100644 --- a/gnuradio-runtime/lib/block.cc +++ b/gnuradio-runtime/lib/block.cc @@ -739,6 +739,11 @@ namespace gr { d_pc_rpc_set = true; #if defined(GR_CTRLPORT) && defined(GR_PERFORMANCE_COUNTERS) d_rpc_vars.push_back( + rpcbasic_sptr(new rpcbasic_register_trigger<block>( + alias(), "reset_perf_counters", &block::reset_perf_counters, + "Reset the Performance Counters", RPC_PRIVLVL_MIN))); + + d_rpc_vars.push_back( rpcbasic_sptr(new rpcbasic_register_get<block, float>( alias(), "noutput_items", &block::pc_noutput_items, pmt::mp(0), pmt::mp(32768), pmt::mp(0), diff --git a/gnuradio-runtime/lib/controlport/rpcpmtconverters_ice.cc b/gnuradio-runtime/lib/controlport/rpcpmtconverters_ice.cc index efd2a5599c..1477ae2c8d 100644 --- a/gnuradio-runtime/lib/controlport/rpcpmtconverters_ice.cc +++ b/gnuradio-runtime/lib/controlport/rpcpmtconverters_ice.cc @@ -54,7 +54,7 @@ rpcpmtconverter::from_pmt(const pmt::pmt_t& knob, const Ice::Current& c) size_t size(pmt::length(knob)); const float* start((const float*) pmt::c32vector_elements(knob,size)); return new GNURadio::KnobVecF(std::vector<float>(start,start+size*2)); - } + } else if (pmt::is_s32vector(knob)) { size_t size(pmt::length(knob)); const int* start((const int*) pmt::s32vector_elements(knob,size)); @@ -69,7 +69,7 @@ rpcpmtconverter::from_pmt(const pmt::pmt_t& knob, const Ice::Current& c) size_t size(pmt::length(knob)); const float* start((const float*) pmt::f32vector_elements(knob,size)); return new GNURadio::KnobVecF(std::vector<float>(start,start+size)); - } + } else if (pmt::is_u8vector(knob)) { size_t size(pmt::length(knob)); const uint8_t* start((const uint8_t*) pmt::u8vector_elements(knob,size)); @@ -112,7 +112,10 @@ rpcpmtconverter::to_pmt(const GNURadio::KnobPtr& knob, const Ice::Current& c) } else if(id == "KnobB") { GNURadio::KnobBPtr k(GNURadio::KnobBPtr::dynamicCast(knob)); - return pmt::mp(k->value); + if((k->value == true) || (k->value > 0)) + return pmt::PMT_T; + else + return pmt::PMT_F; } else if(id == "KnobC") { GNURadio::KnobCPtr k(GNURadio::KnobCPtr::dynamicCast(knob)); @@ -121,16 +124,16 @@ rpcpmtconverter::to_pmt(const GNURadio::KnobPtr& knob, const Ice::Current& c) else if(id == "KnobL") { GNURadio::KnobLPtr k(GNURadio::KnobLPtr::dynamicCast(knob)); return pmt::mp((long)k->value); - } + } else if(id == "KnobZ") { GNURadio::KnobZPtr k(GNURadio::KnobZPtr::dynamicCast(knob)); std::complex<double> cpx(k->value.re, k->value.im); return pmt::from_complex(cpx); - } + } else if(id == "KnobVecC") { GNURadio::KnobVecCPtr k(GNURadio::KnobVecCPtr::dynamicCast(knob)); return pmt::init_u8vector(k->value.size(), &k->value[0]); - } + } else if(id == "KnobVecI") { GNURadio::KnobVecIPtr k(GNURadio::KnobVecIPtr::dynamicCast(knob)); return pmt::init_s32vector(k->value.size(), &k->value[0]); @@ -144,5 +147,5 @@ rpcpmtconverter::to_pmt(const GNURadio::KnobPtr& knob, const Ice::Current& c) std::cerr << "Error: Don't know how to handle Knob Type: " << id << std::endl; assert(0); } - return pmt::pmt_t(); + return pmt::pmt_t(); } diff --git a/gnuradio-runtime/lib/top_block.cc b/gnuradio-runtime/lib/top_block.cc index 99f8330add..8918a8f12d 100644 --- a/gnuradio-runtime/lib/top_block.cc +++ b/gnuradio-runtime/lib/top_block.cc @@ -140,6 +140,22 @@ namespace gr { if(is_rpc_set()) return; + // Triggers + d_rpc_vars.push_back( + rpcbasic_sptr(new rpcbasic_register_trigger<top_block>( + alias(), "stop", &top_block::stop, + "Stop the flowgraph", RPC_PRIVLVL_MIN))); + + d_rpc_vars.push_back( + rpcbasic_sptr(new rpcbasic_register_trigger<top_block>( + alias(), "lock", &top_block::lock, + "Lock the flowgraph", RPC_PRIVLVL_MIN))); + + d_rpc_vars.push_back( + rpcbasic_sptr(new rpcbasic_register_trigger<top_block>( + alias(), "unlock", &top_block::unlock, + "Unock the flowgraph", RPC_PRIVLVL_MIN))); + // Getters add_rpc_variable( rpcbasic_sptr(new rpcbasic_register_get<top_block, int>( diff --git a/gnuradio-runtime/python/gnuradio/ctrlport/gr-perf-monitorx b/gnuradio-runtime/python/gnuradio/ctrlport/gr-perf-monitorx index 1c6e0741b7..14c0f0bceb 100755 --- a/gnuradio-runtime/python/gnuradio/ctrlport/gr-perf-monitorx +++ b/gnuradio-runtime/python/gnuradio/ctrlport/gr-perf-monitorx @@ -46,7 +46,7 @@ class MAINWindow(QtGui.QMainWindow): return QtGui.QSize(800,600) def __init__(self, radio, port, interface): - + super(MAINWindow, self).__init__() self.conns = [] self.plots = [] @@ -75,7 +75,6 @@ class MAINWindow(QtGui.QMainWindow): icon = QtGui.QIcon(ctrlport.__path__[0] + "/icon.png" ) self.setWindowIcon(icon) - def newSubWindow(self, window, title): child = window; child.setWindowTitle(title) @@ -131,7 +130,6 @@ class MAINWindow(QtGui.QMainWindow): 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", @@ -236,7 +234,7 @@ class ConInfoDialog(QtGui.QDialog): super(ConInfoDialog, self).__init__(parent) self.gridLayout = QtGui.QGridLayout(self) - + self.host = QtGui.QLineEdit(self); self.port = QtGui.QLineEdit(self); @@ -267,7 +265,7 @@ class DataTable(QtGui.QWidget): def __init__(self, radio, G): QtGui.QWidget.__init__( self) - + self.layout = QtGui.QVBoxLayout(self); self.hlayout = QtGui.QHBoxLayout(); self.layout.addLayout(self.hlayout); @@ -325,7 +323,7 @@ class DataTable(QtGui.QWidget): self.timer.start(500) for i in range(0,len(nodes)): - self.perfTable.setItem( + self.perfTable.setItem( i,0, Qt.QTableWidgetItem(nodes[i][0])) @@ -370,7 +368,7 @@ class DataTableBuffers(DataTable): 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): @@ -429,8 +427,8 @@ class DataTableRuntimes(DataTable): sorted_work[self._keymap.index(b)] = (b, work_times[b]) else: sorted_work = work_times.items() - - self.sp.clear(); + + 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), @@ -439,7 +437,7 @@ class DataTableRuntimes(DataTable): 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(); @@ -464,7 +462,7 @@ class MForm(QtGui.QWidget): nodes_stream = self.G_stream.nodes(); nodes_msg = self.G_msg.nodes(); - + # get current buffer depths of all output buffers kl = map(lambda x: "%s::%soutput %% full" % \ (x, self._statistics_table[self._statistic]), @@ -496,7 +494,7 @@ class MForm(QtGui.QWidget): self.G.nodes(), [0.1]*len(self.G.nodes()))) work_times_padded.update(work_times) - + for n in nodes_stream: # ne is the list of edges away from this node! ne = self.G.edges([n],True); @@ -516,7 +514,7 @@ class MForm(QtGui.QWidget): #newweight = buf_vals[n][sourceport] newweight = 0.01; e[2]["weight"] = newweight; - + # set updated weights #self.node_weights = map(lambda x: 20+2000*work_times[x], nodes_stream); self.node_weights = map(lambda x: 20+2000*work_times_padded[x], self.G.nodes()); @@ -528,7 +526,7 @@ class MForm(QtGui.QWidget): 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): @@ -547,13 +545,42 @@ class MForm(QtGui.QWidget): else: sys.exit(1) return - + def rtt(self): self.parent.newSubWindow( DataTableRuntimes(self.radio, self.G_stream), "Runtime Table" ); def bpt(self): self.parent.newSubWindow( DataTableBuffers(self.radio, self.G_stream), "Buffers Table" ); + def resetPCs(self): + knob = GNURadio.KnobB() + knob.value = False + km = {} + for b in self.blocks_list: + km[b + "::reset_perf_counters"] = knob + k = self.radio.set(km) + + def toggleFlowgraph(self): + if self.pauseFGAct.isChecked(): + self.pauseFlowgraph() + else: + self.unpauseFlowgraph() + + def pauseFlowgraph(self): + knob = GNURadio.KnobB() + knob.value = False + km = {} + km[self.top_block + "::lock"] = knob + km[self.top_block + "::stop"] = knob + k = self.radio.set(km) + + def unpauseFlowgraph(self): + knob = GNURadio.KnobB() + knob.value = False + km = {} + km[self.top_block + "::unlock"] = knob + k = self.radio.set(km) + def stat_changed(self, index): self._statistic = str(self.stattype.currentText()) @@ -582,7 +609,7 @@ class MForm(QtGui.QWidget): else: self.radio = None return - + self.uid = uid self.parent = parent @@ -593,7 +620,7 @@ class MForm(QtGui.QWidget): 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() @@ -606,6 +633,21 @@ class MForm(QtGui.QWidget): self.bptBut.setDefaultAction(self.bptAct); self.ctlBox.addWidget(self.bptBut); + self.resetPCsAct = QtGui.QAction("Reset", self, + statusTip="Reset all Performance Counters", + triggered=self.resetPCs) + self.resetPCsBut = Qt.QToolButton() + self.resetPCsBut.setDefaultAction(self.resetPCsAct); + self.ctlBox.addWidget(self.resetPCsBut); + + self.pauseFGAct = QtGui.QAction("Pause", self, + statusTip="Pause the Flowgraph", + triggered=self.toggleFlowgraph) + self.pauseFGAct.setCheckable(True) + self.pauseFGBut = Qt.QToolButton() + self.pauseFGBut.setDefaultAction(self.pauseFGAct); + self.ctlBox.addWidget(self.pauseFGBut); + self.prevent_clock_change = True; self.clockKey = None; self.clocks = {"MONOTONIC":1, "THREAD":3}; @@ -656,6 +698,7 @@ class MForm(QtGui.QWidget): keyname = propname[1] if(keyname == "edge list"): edgelist = knobs[k].value + self.top_block = blockname elif(keyname == "msg edges list"): msgedgelist = knobs[k].value elif(blockname not in tmplist): @@ -663,12 +706,14 @@ class MForm(QtGui.QWidget): 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) + self.blocks_list = tmplist edges = edgelist.split("\n")[0:-1] msgedges = msgedgelist.split("\n")[0:-1] @@ -686,7 +731,7 @@ class MForm(QtGui.QWidget): _e = e.split("->") edgepairs_msg.append( (_e[0].split(":")[0], _e[1].split(":")[0], {"type":"msg", "sourceport":_e[0].split(":")[1]}) ); - + self.G = nx.MultiDiGraph(); self.G_stream = nx.MultiDiGraph(); self.G_msg = nx.MultiDiGraph(); @@ -769,14 +814,14 @@ class MForm(QtGui.QWidget): 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(); + self.sp.clear(); plt.figure(self.f.number) plt.subplot(111); - nx.draw(self.G, self.pos, + 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), diff --git a/gnuradio-runtime/python/gnuradio/ctrlport/icon.png b/gnuradio-runtime/python/gnuradio/ctrlport/icon.png Binary files differindex 4beb204428..1c27323696 100644 --- a/gnuradio-runtime/python/gnuradio/ctrlport/icon.png +++ b/gnuradio-runtime/python/gnuradio/ctrlport/icon.png |