Imported Upstream version 3.2.2
[debian/gnuradio] / gr-wxgui / src / python / const_window.py
1 #
2 # Copyright 2008 Free Software Foundation, Inc.
3 #
4 # This file is part of GNU Radio
5 #
6 # GNU Radio is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3, or (at your option)
9 # any later version.
10 #
11 # GNU Radio is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with GNU Radio; see the file COPYING.  If not, write to
18 # the Free Software Foundation, Inc., 51 Franklin Street,
19 # Boston, MA 02110-1301, USA.
20 #
21
22 ##################################################
23 # Imports
24 ##################################################
25 import plotter
26 import common
27 import wx
28 import numpy
29 import math
30 import pubsub
31 from constants import *
32 from gnuradio import gr #for gr.prefs
33 import forms
34
35 ##################################################
36 # Constants
37 ##################################################
38 SLIDER_STEPS = 200
39 ALPHA_MIN_EXP, ALPHA_MAX_EXP = -6, -0.301
40 GAIN_MU_MIN_EXP, GAIN_MU_MAX_EXP = -6, -0.301
41 DEFAULT_FRAME_RATE = gr.prefs().get_long('wxgui', 'const_rate', 5)
42 DEFAULT_WIN_SIZE = (500, 400)
43 DEFAULT_CONST_SIZE = gr.prefs().get_long('wxgui', 'const_size', 2048)
44 CONST_PLOT_COLOR_SPEC = (0, 0, 1)
45 MARKER_TYPES = (
46         ('Dot Small', 1.0),
47         ('Dot Medium', 2.0),
48         ('Dot Large', 3.0),
49         ('Line Link', None),
50 )
51 DEFAULT_MARKER_TYPE = 2.0
52
53 ##################################################
54 # Constellation window control panel
55 ##################################################
56 class control_panel(wx.Panel):
57         """
58         A control panel with wx widgits to control the plotter.
59         """
60         def __init__(self, parent):
61                 """
62                 Create a new control panel.
63                 @param parent the wx parent window
64                 """
65                 self.parent = parent
66                 wx.Panel.__init__(self, parent, style=wx.SUNKEN_BORDER)
67                 control_box = forms.static_box_sizer(
68                         parent=self, label='Options',
69                         bold=True, orient=wx.VERTICAL,
70                 )
71                 #alpha
72                 control_box.AddStretchSpacer()
73                 forms.text_box(
74                         sizer=control_box, parent=self, label='Alpha',
75                         converter=forms.float_converter(),
76                         ps=parent, key=ALPHA_KEY,
77                 )
78                 forms.log_slider(
79                         sizer=control_box, parent=self,
80                         min_exp=ALPHA_MIN_EXP,
81                         max_exp=ALPHA_MAX_EXP,
82                         num_steps=SLIDER_STEPS,
83                         ps=parent, key=ALPHA_KEY,
84                 )
85                 #gain_mu
86                 control_box.AddStretchSpacer()
87                 forms.text_box(
88                         sizer=control_box, parent=self, label='Gain Mu',
89                         converter=forms.float_converter(),
90                         ps=parent, key=GAIN_MU_KEY,
91                 )
92                 forms.log_slider(
93                         sizer=control_box, parent=self,
94                         min_exp=GAIN_MU_MIN_EXP,
95                         max_exp=GAIN_MU_MAX_EXP,
96                         num_steps=SLIDER_STEPS,
97                         ps=parent, key=GAIN_MU_KEY,
98                 )
99                 #marker
100                 control_box.AddStretchSpacer()
101                 forms.drop_down(
102                         sizer=control_box, parent=self,
103                         ps=parent, key=MARKER_KEY, label='Marker',
104                         choices=map(lambda x: x[1], MARKER_TYPES),
105                         labels=map(lambda x: x[0], MARKER_TYPES),
106                 )
107                 #run/stop
108                 control_box.AddStretchSpacer()
109                 forms.toggle_button(
110                         sizer=control_box, parent=self,
111                         true_label='Stop', false_label='Run',
112                         ps=parent, key=RUNNING_KEY,
113                 )
114                 #set sizer
115                 self.SetSizerAndFit(control_box)
116
117 ##################################################
118 # Constellation window with plotter and control panel
119 ##################################################
120 class const_window(wx.Panel, pubsub.pubsub):
121         def __init__(
122                 self,
123                 parent,
124                 controller,
125                 size,
126                 title,
127                 msg_key,
128                 alpha_key,
129                 beta_key,
130                 gain_mu_key,
131                 gain_omega_key,
132                 omega_key,
133                 sample_rate_key,
134         ):
135                 pubsub.pubsub.__init__(self)
136                 #proxy the keys
137                 self.proxy(MSG_KEY, controller, msg_key)
138                 self.proxy(ALPHA_KEY, controller, alpha_key)
139                 self.proxy(BETA_KEY, controller, beta_key)
140                 self.proxy(GAIN_MU_KEY, controller, gain_mu_key)
141                 self.proxy(GAIN_OMEGA_KEY, controller, gain_omega_key)
142                 self.proxy(OMEGA_KEY, controller, omega_key)
143                 self.proxy(SAMPLE_RATE_KEY, controller, sample_rate_key)
144                 #initialize values
145                 self[RUNNING_KEY] = True
146                 self[X_DIVS_KEY] = 8
147                 self[Y_DIVS_KEY] = 8
148                 self[MARKER_KEY] = DEFAULT_MARKER_TYPE
149                 #init panel and plot
150                 wx.Panel.__init__(self, parent, style=wx.SIMPLE_BORDER)
151                 self.plotter = plotter.channel_plotter(self)
152                 self.plotter.SetSize(wx.Size(*size))
153                 self.plotter.set_title(title)
154                 self.plotter.set_x_label('Inphase')
155                 self.plotter.set_y_label('Quadrature')
156                 self.plotter.enable_point_label(True)
157                 self.plotter.enable_grid_lines(True)
158                 #setup the box with plot and controls
159                 self.control_panel = control_panel(self)
160                 main_box = wx.BoxSizer(wx.HORIZONTAL)
161                 main_box.Add(self.plotter, 1, wx.EXPAND)
162                 main_box.Add(self.control_panel, 0, wx.EXPAND)
163                 self.SetSizerAndFit(main_box)
164                 #alpha and gain mu 2nd orders
165                 def set_beta(alpha): self[BETA_KEY] = .25*alpha**2
166                 self.subscribe(ALPHA_KEY, set_beta)
167                 def set_gain_omega(gain_mu): self[GAIN_OMEGA_KEY] = .25*gain_mu**2
168                 self.subscribe(GAIN_MU_KEY, set_gain_omega)
169                 #register events
170                 self.subscribe(MSG_KEY, self.handle_msg)
171                 self.subscribe(X_DIVS_KEY, self.update_grid)
172                 self.subscribe(Y_DIVS_KEY, self.update_grid)
173                 #initial update
174                 self.update_grid()
175
176         def handle_msg(self, msg):
177                 """
178                 Plot the samples onto the complex grid.
179                 @param msg the array of complex samples
180                 """
181                 if not self[RUNNING_KEY]: return
182                 #convert to complex floating point numbers
183                 samples = numpy.fromstring(msg, numpy.complex64)
184                 real = numpy.real(samples)
185                 imag = numpy.imag(samples)
186                 #plot
187                 self.plotter.set_waveform(
188                         channel=0,
189                         samples=(real, imag),
190                         color_spec=CONST_PLOT_COLOR_SPEC,
191                         marker=self[MARKER_KEY],
192                 )
193                 #update the plotter
194                 self.plotter.update()
195
196         def update_grid(self):
197                 #update the x axis
198                 x_max = 2.0
199                 self.plotter.set_x_grid(-x_max, x_max, common.get_clean_num(2.0*x_max/self[X_DIVS_KEY]))
200                 #update the y axis
201                 y_max = 2.0
202                 self.plotter.set_y_grid(-y_max, y_max, common.get_clean_num(2.0*y_max/self[Y_DIVS_KEY]))
203                 #update plotter
204                 self.plotter.update()
205
206
207
208