2 # Copyright 2008 Free Software Foundation, Inc.
4 # This file is part of GNU Radio
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)
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.
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.
22 ##################################################
24 ##################################################
31 from constants import *
32 from gnuradio import gr #for gr.prefs
35 ##################################################
37 ##################################################
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)
51 DEFAULT_MARKER_TYPE = 2.0
53 ##################################################
54 # Constellation window control panel
55 ##################################################
56 class control_panel(wx.Panel):
58 A control panel with wx widgits to control the plotter.
60 def __init__(self, parent):
62 Create a new control panel.
63 @param parent the wx parent window
66 wx.Panel.__init__(self, parent, style=wx.SUNKEN_BORDER)
67 parent[SHOW_CONTROL_PANEL_KEY] = True
68 parent.subscribe(SHOW_CONTROL_PANEL_KEY, self.Show)
69 control_box = forms.static_box_sizer(
70 parent=self, label='Options',
71 bold=True, orient=wx.VERTICAL,
74 control_box.AddStretchSpacer()
76 sizer=control_box, parent=self, label='Alpha',
77 converter=forms.float_converter(),
78 ps=parent, key=ALPHA_KEY,
81 sizer=control_box, parent=self,
82 min_exp=ALPHA_MIN_EXP,
83 max_exp=ALPHA_MAX_EXP,
84 num_steps=SLIDER_STEPS,
85 ps=parent, key=ALPHA_KEY,
88 control_box.AddStretchSpacer()
90 sizer=control_box, parent=self, label='Gain Mu',
91 converter=forms.float_converter(),
92 ps=parent, key=GAIN_MU_KEY,
95 sizer=control_box, parent=self,
96 min_exp=GAIN_MU_MIN_EXP,
97 max_exp=GAIN_MU_MAX_EXP,
98 num_steps=SLIDER_STEPS,
99 ps=parent, key=GAIN_MU_KEY,
102 control_box.AddStretchSpacer()
104 sizer=control_box, parent=self,
105 ps=parent, key=MARKER_KEY, label='Marker',
106 choices=map(lambda x: x[1], MARKER_TYPES),
107 labels=map(lambda x: x[0], MARKER_TYPES),
110 control_box.AddStretchSpacer()
112 sizer=control_box, parent=self,
113 true_label='Stop', false_label='Run',
114 ps=parent, key=RUNNING_KEY,
117 self.SetSizerAndFit(control_box)
119 ##################################################
120 # Constellation window with plotter and control panel
121 ##################################################
122 class const_window(wx.Panel, pubsub.pubsub):
137 pubsub.pubsub.__init__(self)
139 self.proxy(MSG_KEY, controller, msg_key)
140 self.proxy(ALPHA_KEY, controller, alpha_key)
141 self.proxy(BETA_KEY, controller, beta_key)
142 self.proxy(GAIN_MU_KEY, controller, gain_mu_key)
143 self.proxy(GAIN_OMEGA_KEY, controller, gain_omega_key)
144 self.proxy(OMEGA_KEY, controller, omega_key)
145 self.proxy(SAMPLE_RATE_KEY, controller, sample_rate_key)
147 self[RUNNING_KEY] = True
150 self[MARKER_KEY] = DEFAULT_MARKER_TYPE
152 wx.Panel.__init__(self, parent, style=wx.SIMPLE_BORDER)
153 self.plotter = plotter.channel_plotter(self)
154 self.plotter.SetSize(wx.Size(*size))
155 self.plotter.set_title(title)
156 self.plotter.set_x_label('Inphase')
157 self.plotter.set_y_label('Quadrature')
158 self.plotter.enable_point_label(True)
159 self.plotter.enable_grid_lines(True)
160 #setup the box with plot and controls
161 self.control_panel = control_panel(self)
162 main_box = wx.BoxSizer(wx.HORIZONTAL)
163 main_box.Add(self.plotter, 1, wx.EXPAND)
164 main_box.Add(self.control_panel, 0, wx.EXPAND)
165 self.SetSizerAndFit(main_box)
166 #alpha and gain mu 2nd orders
167 def set_beta(alpha): self[BETA_KEY] = .25*alpha**2
168 self.subscribe(ALPHA_KEY, set_beta)
169 def set_gain_omega(gain_mu): self[GAIN_OMEGA_KEY] = .25*gain_mu**2
170 self.subscribe(GAIN_MU_KEY, set_gain_omega)
172 self.subscribe(MSG_KEY, self.handle_msg)
173 self.subscribe(X_DIVS_KEY, self.update_grid)
174 self.subscribe(Y_DIVS_KEY, self.update_grid)
178 def handle_msg(self, msg):
180 Plot the samples onto the complex grid.
181 @param msg the array of complex samples
183 if not self[RUNNING_KEY]: return
184 #convert to complex floating point numbers
185 samples = numpy.fromstring(msg, numpy.complex64)
186 real = numpy.real(samples)
187 imag = numpy.imag(samples)
189 self.plotter.set_waveform(
191 samples=(real, imag),
192 color_spec=CONST_PLOT_COLOR_SPEC,
193 marker=self[MARKER_KEY],
196 self.plotter.update()
198 def update_grid(self):
201 self.plotter.set_x_grid(-x_max, x_max, common.get_clean_num(2.0*x_max/self[X_DIVS_KEY]))
204 self.plotter.set_y_grid(-y_max, y_max, common.get_clean_num(2.0*y_max/self[Y_DIVS_KEY]))
206 self.plotter.update()