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 *
33 ##################################################
35 ##################################################
37 ALPHA_MIN_EXP, ALPHA_MAX_EXP = -6, -0.301
38 GAIN_MU_MIN_EXP, GAIN_MU_MAX_EXP = -6, -0.301
39 DEFAULT_FRAME_RATE = 5
40 DEFAULT_WIN_SIZE = (500, 400)
41 DEFAULT_CONST_SIZE = 2048
42 CONST_PLOT_COLOR_SPEC = (0, 0, 1)
49 DEFAULT_MARKER_TYPE = 2.0
51 ##################################################
52 # Constellation window control panel
53 ##################################################
54 class control_panel(wx.Panel):
56 A control panel with wx widgits to control the plotter.
58 def __init__(self, parent):
60 Create a new control panel.
61 @param parent the wx parent window
64 wx.Panel.__init__(self, parent, -1, style=wx.SUNKEN_BORDER)
65 control_box = wx.BoxSizer(wx.VERTICAL)
68 control_box.AddStretchSpacer()
69 control_box.Add(common.LabelText(self, 'Options'), 0, wx.ALIGN_CENTER)
71 control_box.AddStretchSpacer()
72 self.marker_chooser = common.DropDownController(self, 'Marker', MARKER_TYPES, parent, MARKER_KEY)
73 control_box.Add(self.marker_chooser, 0, wx.EXPAND)
75 control_box.AddStretchSpacer()
76 self.alpha_slider = common.LogSliderController(
78 ALPHA_MIN_EXP, ALPHA_MAX_EXP, SLIDER_STEPS,
79 parent.ext_controller, parent.alpha_key,
81 control_box.Add(self.alpha_slider, 0, wx.EXPAND)
83 control_box.AddStretchSpacer()
84 self.gain_mu_slider = common.LogSliderController(
86 GAIN_MU_MIN_EXP, GAIN_MU_MAX_EXP, SLIDER_STEPS,
87 parent.ext_controller, parent.gain_mu_key,
89 control_box.Add(self.gain_mu_slider, 0, wx.EXPAND)
91 control_box.AddStretchSpacer()
92 self.run_button = common.ToggleButtonController(self, parent, RUNNING_KEY, 'Stop', 'Run')
93 control_box.Add(self.run_button, 0, wx.EXPAND)
95 self.SetSizerAndFit(control_box)
97 ##################################################
98 # Constellation window with plotter and control panel
99 ##################################################
100 class const_window(wx.Panel, pubsub.pubsub, common.prop_setter):
113 pubsub.pubsub.__init__(self)
115 self.ext_controller = controller
116 self.alpha_key = alpha_key
117 self.beta_key = beta_key
118 self.gain_mu_key = gain_mu_key
119 self.gain_omega_key = gain_omega_key
121 wx.Panel.__init__(self, parent, -1, style=wx.SIMPLE_BORDER)
122 self.plotter = plotter.channel_plotter(self)
123 self.plotter.SetSize(wx.Size(*size))
124 self.plotter.set_title(title)
125 self.plotter.set_x_label('Inphase')
126 self.plotter.set_y_label('Quadrature')
127 self.plotter.enable_point_label(True)
128 #setup the box with plot and controls
129 self.control_panel = control_panel(self)
130 main_box = wx.BoxSizer(wx.HORIZONTAL)
131 main_box.Add(self.plotter, 1, wx.EXPAND)
132 main_box.Add(self.control_panel, 0, wx.EXPAND)
133 self.SetSizerAndFit(main_box)
134 #alpha and gain mu 2nd orders
135 def set_beta(alpha): self.ext_controller[self.beta_key] = .25*alpha**2
136 self.ext_controller.subscribe(self.alpha_key, set_beta)
137 def set_gain_omega(gain_mu): self.ext_controller[self.gain_omega_key] = .25*gain_mu**2
138 self.ext_controller.subscribe(self.gain_mu_key, set_gain_omega)
140 self.ext_controller[self.alpha_key] = self.ext_controller[self.alpha_key]
141 self.ext_controller[self.gain_mu_key] = self.ext_controller[self.gain_mu_key]
142 self._register_set_prop(self, RUNNING_KEY, True)
143 self._register_set_prop(self, X_DIVS_KEY, 8)
144 self._register_set_prop(self, Y_DIVS_KEY, 8)
145 self._register_set_prop(self, MARKER_KEY, DEFAULT_MARKER_TYPE)
147 self.ext_controller.subscribe(msg_key, self.handle_msg)
149 X_DIVS_KEY, Y_DIVS_KEY,
150 ): self.subscribe(key, self.update_grid)
154 def handle_msg(self, msg):
156 Plot the samples onto the complex grid.
157 @param msg the array of complex samples
159 if not self[RUNNING_KEY]: return
160 #convert to complex floating point numbers
161 samples = numpy.fromstring(msg, numpy.complex64)
162 real = numpy.real(samples)
163 imag = numpy.imag(samples)
165 self.plotter.set_waveform(
167 samples=(real, imag),
168 color_spec=CONST_PLOT_COLOR_SPEC,
169 marker=self[MARKER_KEY],
172 self.plotter.update()
174 def update_grid(self):
176 x_divs = self[X_DIVS_KEY]
177 y_divs = self[Y_DIVS_KEY]
180 self.plotter.set_x_grid(-x_max, x_max, common.get_clean_num(2.0*x_max/x_divs))
183 self.plotter.set_y_grid(-y_max, y_max, common.get_clean_num(2.0*y_max/y_divs))
185 self.plotter.update()