Statistics
| Branch: | Tag: | Revision:

root / gr-wxgui / src / python / const_window.py @ 2956c43f

History | View | Annotate | Download (5.8 kB)

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
33
##################################################
34
# Constants
35
##################################################
36
SLIDER_STEPS = 200
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)
43
MARKER_TYPES = (
44
        ('Dot Small', 1.0),
45
        ('Dot Medium', 2.0),
46
        ('Dot Large', 3.0),
47
        ('Line Link', None),
48
)
49
DEFAULT_MARKER_TYPE = 2.0
50
51
##################################################
52
# Constellation window control panel
53
##################################################
54
class control_panel(wx.Panel):
55
        """!
56
        A control panel with wx widgits to control the plotter.
57
        """
58
        def __init__(self, parent):
59
                """!
60
                Create a new control panel.
61
                @param parent the wx parent window
62
                """
63
                self.parent = parent
64
                wx.Panel.__init__(self, parent, -1, style=wx.SUNKEN_BORDER)
65
                control_box = wx.BoxSizer(wx.VERTICAL)
66
                self.marker_index = 2
67
                #begin control box
68
                control_box.AddStretchSpacer()
69
                control_box.Add(common.LabelText(self, 'Options'), 0, wx.ALIGN_CENTER)
70
                #marker
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)
74
                #alpha
75
                control_box.AddStretchSpacer()
76
                self.alpha_slider = common.LogSliderController(
77
                        self, 'Alpha',
78
                        ALPHA_MIN_EXP, ALPHA_MAX_EXP, SLIDER_STEPS,
79
                        parent.ext_controller, parent.alpha_key,
80
                )
81
                control_box.Add(self.alpha_slider, 0, wx.EXPAND)
82
                #gain_mu
83
                control_box.AddStretchSpacer()
84
                self.gain_mu_slider = common.LogSliderController(
85
                        self, 'Gain Mu',
86
                        GAIN_MU_MIN_EXP, GAIN_MU_MAX_EXP, SLIDER_STEPS,
87
                        parent.ext_controller, parent.gain_mu_key,
88
                )
89
                control_box.Add(self.gain_mu_slider, 0, wx.EXPAND)
90
                #run/stop
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)
94
                #set sizer
95
                self.SetSizerAndFit(control_box)
96
97
##################################################
98
# Constellation window with plotter and control panel
99
##################################################
100
class const_window(wx.Panel, pubsub.pubsub, common.prop_setter):
101
        def __init__(
102
                self,
103
                parent,
104
                controller,
105
                size,
106
                title,
107
                msg_key,
108
                alpha_key,
109
                beta_key,
110
                gain_mu_key,
111
                gain_omega_key,
112
        ):
113
                pubsub.pubsub.__init__(self)
114
                #setup
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
120
                #init panel and plot
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)
139
                #initial setup
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)
146
                #register events
147
                self.ext_controller.subscribe(msg_key, self.handle_msg)
148
                for key in (
149
                        X_DIVS_KEY, Y_DIVS_KEY,
150
                ): self.subscribe(key, self.update_grid)
151
                #initial update
152
                self.update_grid()
153
154
        def handle_msg(self, msg):
155
                """!
156
                Plot the samples onto the complex grid.
157
                @param msg the array of complex samples
158
                """
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)
164
                #plot
165
                self.plotter.set_waveform(
166
                        channel=0,
167
                        samples=(real, imag),
168
                        color_spec=CONST_PLOT_COLOR_SPEC,
169
                        marker=self[MARKER_KEY],
170
                )
171
                #update the plotter
172
                self.plotter.update()
173
174
        def update_grid(self):
175
                #grid parameters
176
                x_divs = self[X_DIVS_KEY]
177
                y_divs = self[Y_DIVS_KEY]
178
                #update the x axis
179
                x_max = 2.0
180
                self.plotter.set_x_grid(-x_max, x_max, common.get_clean_num(2.0*x_max/x_divs))
181
                #update the y axis
182
                y_max = 2.0
183
                self.plotter.set_y_grid(-y_max, y_max, common.get_clean_num(2.0*y_max/y_divs))
184
                #update plotter
185
                self.plotter.update()
186
187
188
189