plfdtd (0.1.0) | 2012-05-14 18:57 |
pylaf (0.5.0) | 2012-10-18 17:20 |
PyLAFではコンポーネント単位でプログラムを作成していきます。 どのようにコンポーネントを作成し、それぞれを連携させてゆけばよいのか、 振幅変調の学習プログラムを作成しながら説明してゆきます。
正弦波を生成するコンポーネントのコードを示します。 まずは、このコードを実行してみましょう。
FrequencyやPhase Offsetを変更してみてください。 エントリを書き換えて<Enter>を押すとグラフが更新されます。
- from PyLAF import *
- class FGSIN(EasyComponent):
- PLOTTER = Oscilloscope
- def __init__(self,master=None):
- EasyComponent.__init__(self,master)
- self.mag = EasyPort(Variable(1.),'Magnitude [mV]').bind(self.trigger)
- self.freq = EasyPort(Variable(0.01),'Frequency [MHz]').bind(self.trigger)
- self.phase = EasyPort(Variable(0.),'Phase Offset [deg]').bind(self.trigger)
- self.bias = EasyPort(Variable(0.),'Bias Voltage [mV]').bind(self.trigger)
- self.dt = EasyPort(Variable(1.),'Time Step [us]').bind(self.trigger)
- self.tend = EasyPort(Variable(500.),'End [us]').bind(self.trigger)
- def trigger(self):
- t = arange(0.,self.tend.get(),self.dt.get())
- w = sin(2 * pi * self.freq.get() * t + self.phase.get() / 180. * pi)
- self.sig_out.set(self.mag.get() * w + self.bias.get())
- def test(master=None):
- o = App(master,FGSIN); o.pack()
- o.component.trigger()
- if __name__ == '__main__':
- test(Tkinter.Tk())
- Tkinter.mainloop()
新しくコンポーネントを作成してみましょう。
Pythonでは字下げもプログラム上の意味がありますので、 スペースの数などもまったく同じになるようにタイプします。
FGSINの出力ポートにスペアナを接続してみます。
test()関数を以下のように変更します。PyLAFにビルトインされているSpectrumコンポーネントはsig_inポートのデータが
更新されると、sig_inのデータをフーリエ変換して表示します。例題ではFGSINのsig_outとSpectrumのsig_inとがリンクされています。
FGSINで表示されている時間波形のフーリエ変換が表示されていることがわかります。
def test(master=None): o = App(master,FGSIN); o.pack()↓
def test(master=None): o = App(master,FGSIN); o.pack() v = App(Tkinter.Toplevel(master),Spectrum); v.pack() o.component.sig_out.link(v.component.sig_in)
- from PyLAF import *
- class FGSIN(EasyComponent):
- PLOTTER = Oscilloscope
- def __init__(self,master=None):
- EasyComponent.__init__(self,master)
- self.mag = EasyPort(Variable(1.),'Magnitude [mV]').bind(self.trigger)
- self.freq = EasyPort(Variable(0.01),'Frequency [MHz]').bind(self.trigger)
- self.phase = EasyPort(Variable(0.),'Phase Offset [deg]').bind(self.trigger)
- self.bias = EasyPort(Variable(0.),'Bias Voltage [mV]').bind(self.trigger)
- self.dt = EasyPort(Variable(1.),'Time Step [us]').bind(self.trigger)
- self.tend = EasyPort(Variable(500.),'End [us]').bind(self.trigger)
- def trigger(self):
- t = arange(0.,self.tend.get(),self.dt.get())
- w = sin(2 * pi * self.freq.get() * t + self.phase.get() / 180. * pi)
- self.sig_out.set(self.mag.get() * w + self.bias.get())
- def test(master=None):
- o = App(master,FGSIN); o.pack()
- v = App(Tkinter.Toplevel(master),Spectrum); v.pack()
- o.component.sig_out.link(v.component.sig_in)
- if __name__ == '__main__':
- test(Tkinter.Tk())
- Tkinter.mainloop()
FGSINのプロッタを変更してみましょう。
実行すると、スペクトルが表示されますが、周波数範囲が広くてよくわかりません。 スペクトルの表示部分で右クリックするとポップアップメニューが開きます。 Consoleを選ぶと横軸設定が開くので、XMIN,XMAXを0,0.2程度にしてみましょう。
Plugin Error: attach file not found: MODAM4.pngPlugin Error: attach file not found: MODAM4.py
1プロット1エントリーパネルという基本的なプログラムはEasyComponentを継承して作ります。 クラス変数PLOTTERでプロットの種別を設定します。いまのところ、XYPlot、Oscilloscope、Spectrum、Constellationを設定できます。 PLOTTERをSpectrumに変更して実行してみてください。ビューがスペクトル表示に変更されます。
GUIのEntryから操作したいパラメータを以下の書式で与えます。
self.変数名 = EasyPort(Variable(初期値),ラベル).bind(self.trigger)
例えば、以下のコードは「初期値が浮動小数点型1.のmagという変数を定義せよ。GUIに表示する際のラベルは'Magnitude mV'とする。 エントリが更新された際にはtrigger()メソッドを起動する。」という意味です。 定義された順番にGUIに配置されてゆきます。
self.mag = EasyPort(Variable(1.),'Magnitude [mV]').bind(self.trigger)
コンポーネントを実行する際には、AppまたはEmbedというイクイップメントクラスでラップします。 イクイップメントクラスはコンポーネントが保持するGUIやメニュー、コンポーネントをGUIツールキットの 適切な場所に配置して実行可能な状態にします。
o = App(master,FGSIN); o.pack()
ロジックは慣習的にtrigger()メソッドに記述します。TkitnerのDoubleVarなどと同様に、GUIのエントリーパネルに保持されている内容を取得するには、 get()メソッドを、設定するにはset()メソッドを使用します。 コンポーネントの出力はsig_outメンバに対してset()するようにしてください。
t = arange(0.,self.tend.get(),self.dt.get()) # 0からtendまで増分dtで増加する数列をtに代入する w = sin(2 * pi * self.freq.get() * t + self.phase.get() / 180. * pi) # 周波数freq(MHz)、位相phase(度)の正弦波をwに代入する self.sig_out.set(self.mag.get() * w + self.bias.get()) # 振幅をmag倍、バイアスをbias分だけ加算してsig_outに代入するsig_outはエントリーパネルに表示するのではなく、 他のコンポーネントとの連携をとるためのインスタンス変数です。 EasyComponent中で以下のように定義されています。
self.sig_out = Port(Variable(array([])))EasyComponentではsig_outポートはPLOTTERコンポーネントのsig_inポートにリンクしています。 sig_outにsetしたデータがPLOTTERコンポーネントに表示されます。
frm = Frame(master) if not self.PLOTTER == None: v = self.__class__.PLOTTER(frm,pltcnf); v.plot(); v.show(); v.pack() setattr(frm,'plotter',v) self.sig_out.insertlink(0,v.sig_in)