由于快速输入流到 GNU Radio 块,绘图冻结
Plot freezing because of fast input stream to a GNU Radio block
我已经实现了一个 sync block
,它使用 input_items
值在其 work
函数中绘图。现在的问题是绘图机制对于输入流来说不够快(input_items
的值不断变化)。
我尽量简化了代码并添加了注释。这是:
....
import matplotlib
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigCanvas
from matplotlib.backends.backend_wx import NavigationToolbar2Wx
from matplotlib.figure import Figure
temp = ''
class xyz(gr.sync_block):
def __init__(self,parent,title,order):
a = []
self.count = 1
gr.sync_block.__init__(self,
name="xyz",
in_sig=[numpy.float32,numpy.float32],
out_sig=None)
self.win = xyzPlot(parent) #I have a Top Block(wxFrame). I am just making it the parent of xyzPlot(wxPanel) here.
def work(self, input_items, output_items):
global temp
if (self.count == 1):
temp = input_items+list()
bool = not(np.allclose(temp,input_items))#bool will be true if the value of `input_items` changes.
.......
#the code that evaluates z1,z2 depending on the value of input_items
.......
if ( bool or self.count == 1 ):
#If bool is true or it is the first time then I am calling plot() which plots the graph.
self.win.plot(tf(self.z1,self.z3),None,True,True,True,True)
self.count = 0
temp = input_items+list()
return len(input_items[0])
class xyzPlot(wx.Panel):
def __init__(self, parent, dB=None, Hz=None, deg=None):
wx.Panel.__init__(self , parent , -1 ,size=(600,475))
self.fig = Figure()
self.axes = self.fig.add_subplot(111)
def plot(self, syslist, omega=None, dB=None, Hz=None, deg=None, Plot=True, *args , **kwargs):
self.axes.clear() #I clear the graph here so that new values can be plotted.
.....
self.axes.semilogx(omega,mag,*args,**kwargs)
self.canvas = FigCanvas(self, -1, self.fig)
self.canvas.draw()
如您所见,我正在使用 wxPython,但每当我将 input_items
的值更改得太快时,面板就会冻结(如果我更改得慢,它会工作正常)。有什么建议吗?我是新手。
引用我给了:
This will quickly also get a multithreading problem. To be clear: What
you're trying to do (call a plotting function from a block thread) is
problematic and usually won't work.
问题是您在复杂的多线程环境中工作:
- 每个 GNU Radio 块都在自己的线程中工作
- WX Gui 主循环不断运行以更新屏幕。
您在这里所做的是,从 GNU Radio 块线程更改 window 中显示的内容。这是一件坏事,因为它改变了 WX Gui 线程上下文中的内容。这个 可以 工作,如果这些更改不冲突,并且如果 WX Gui 线程在您更改它时不访问此类数据(在某些时候,它必须访问它——否则,没有人会更新您的 window).
这是所有更新的 GUI 的共同问题,不仅是 GNU Radio!
是否发生这种情况仅仅是概率的情况:显示更新缓慢时,您发生冲突的概率很低,但是当您经常更新时,它接近 1。
现有的可视化是用 C++ 编写的,并且非常小心地以正确的方式做事——也就是说,让你的 Gui 工具包(在你的情况下是 WX,尽管我明确推荐,并且已经推荐)离开从那里)知道东西需要更新,然后为 WX 提供一个功能来更新它自己的线程中的显示。
我已经实现了一个 sync block
,它使用 input_items
值在其 work
函数中绘图。现在的问题是绘图机制对于输入流来说不够快(input_items
的值不断变化)。
我尽量简化了代码并添加了注释。这是:
....
import matplotlib
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigCanvas
from matplotlib.backends.backend_wx import NavigationToolbar2Wx
from matplotlib.figure import Figure
temp = ''
class xyz(gr.sync_block):
def __init__(self,parent,title,order):
a = []
self.count = 1
gr.sync_block.__init__(self,
name="xyz",
in_sig=[numpy.float32,numpy.float32],
out_sig=None)
self.win = xyzPlot(parent) #I have a Top Block(wxFrame). I am just making it the parent of xyzPlot(wxPanel) here.
def work(self, input_items, output_items):
global temp
if (self.count == 1):
temp = input_items+list()
bool = not(np.allclose(temp,input_items))#bool will be true if the value of `input_items` changes.
.......
#the code that evaluates z1,z2 depending on the value of input_items
.......
if ( bool or self.count == 1 ):
#If bool is true or it is the first time then I am calling plot() which plots the graph.
self.win.plot(tf(self.z1,self.z3),None,True,True,True,True)
self.count = 0
temp = input_items+list()
return len(input_items[0])
class xyzPlot(wx.Panel):
def __init__(self, parent, dB=None, Hz=None, deg=None):
wx.Panel.__init__(self , parent , -1 ,size=(600,475))
self.fig = Figure()
self.axes = self.fig.add_subplot(111)
def plot(self, syslist, omega=None, dB=None, Hz=None, deg=None, Plot=True, *args , **kwargs):
self.axes.clear() #I clear the graph here so that new values can be plotted.
.....
self.axes.semilogx(omega,mag,*args,**kwargs)
self.canvas = FigCanvas(self, -1, self.fig)
self.canvas.draw()
如您所见,我正在使用 wxPython,但每当我将 input_items
的值更改得太快时,面板就会冻结(如果我更改得慢,它会工作正常)。有什么建议吗?我是新手。
引用
This will quickly also get a multithreading problem. To be clear: What you're trying to do (call a plotting function from a block thread) is problematic and usually won't work.
问题是您在复杂的多线程环境中工作:
- 每个 GNU Radio 块都在自己的线程中工作
- WX Gui 主循环不断运行以更新屏幕。
您在这里所做的是,从 GNU Radio 块线程更改 window 中显示的内容。这是一件坏事,因为它改变了 WX Gui 线程上下文中的内容。这个 可以 工作,如果这些更改不冲突,并且如果 WX Gui 线程在您更改它时不访问此类数据(在某些时候,它必须访问它——否则,没有人会更新您的 window).
这是所有更新的 GUI 的共同问题,不仅是 GNU Radio!
是否发生这种情况仅仅是概率的情况:显示更新缓慢时,您发生冲突的概率很低,但是当您经常更新时,它接近 1。
现有的可视化是用 C++ 编写的,并且非常小心地以正确的方式做事——也就是说,让你的 Gui 工具包(在你的情况下是 WX,尽管我明确推荐,并且已经推荐)离开从那里)知道东西需要更新,然后为 WX 提供一个功能来更新它自己的线程中的显示。