[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] r8767 - gnuradio/branches/developers/jblum/gr-wxglgui/
From: |
jblum |
Subject: |
[Commit-gnuradio] r8767 - gnuradio/branches/developers/jblum/gr-wxglgui/src/python |
Date: |
Tue, 1 Jul 2008 14:06:16 -0600 (MDT) |
Author: jblum
Date: 2008-07-01 14:06:15 -0600 (Tue, 01 Jul 2008)
New Revision: 8767
Modified:
gnuradio/branches/developers/jblum/gr-wxglgui/src/python/common.py
gnuradio/branches/developers/jblum/gr-wxglgui/src/python/constsink.py
gnuradio/branches/developers/jblum/gr-wxglgui/src/python/plotter.py
gnuradio/branches/developers/jblum/gr-wxglgui/src/python/scopesink.py
Log:
scopesink controls, plotter: vertex array
Modified: gnuradio/branches/developers/jblum/gr-wxglgui/src/python/common.py
===================================================================
--- gnuradio/branches/developers/jblum/gr-wxglgui/src/python/common.py
2008-07-01 15:21:21 UTC (rev 8766)
+++ gnuradio/branches/developers/jblum/gr-wxglgui/src/python/common.py
2008-07-01 20:06:15 UTC (rev 8767)
@@ -235,7 +235,7 @@
@param samples the array of real values
@return a tuple of min, max
"""
- scale_factor = 2
+ scale_factor = 3
mean = numpy.average(samples)
rms = scale_factor*((numpy.sum((samples-mean)**2)/len(samples))**.5)
min = mean - rms
Modified: gnuradio/branches/developers/jblum/gr-wxglgui/src/python/constsink.py
===================================================================
--- gnuradio/branches/developers/jblum/gr-wxglgui/src/python/constsink.py
2008-07-01 15:21:21 UTC (rev 8766)
+++ gnuradio/branches/developers/jblum/gr-wxglgui/src/python/constsink.py
2008-07-01 20:06:15 UTC (rev 8767)
@@ -32,7 +32,7 @@
##################################################
# Constants
##################################################
-DEFAULT_FRAME_RATE = 30
+DEFAULT_FRAME_RATE = 5
DEFAULT_WIN_SIZE = (500, 400)
DEFAULT_CONST_SIZE = 1024
CONST_PLOT_COLOR_SPEC = (0, 0, 1)
@@ -126,14 +126,14 @@
if time.time() - self.autorange_ts > AUTORANGE_UPDATE_RATE:
#adjust the x per div
min, max = common.get_min_max(real)
- x_per_div =
common.get_clean_num(1.5*(max-min)/self.x_divs)
+ x_per_div = common.get_clean_num((max-min)/self.x_divs)
if self.x_per_div != x_per_div:
self.set_x_per_div(x_per_div)
#adjust the x offset
x_off = self.x_per_div*round((max+min)/2/self.x_per_div)
if self.x_off != x_off: self.set_x_off(x_off)
#adjust the y per div
min, max = common.get_min_max(imag)
- y_per_div =
common.get_clean_num(1.5*(max-min)/self.y_divs)
+ y_per_div = common.get_clean_num((max-min)/self.y_divs)
if self.y_per_div != y_per_div:
self.set_y_per_div(y_per_div)
#adjust the y offset
y_off = self.y_per_div*round((max+min)/2/self.y_per_div)
@@ -144,7 +144,10 @@
channel=0,
samples=(real, imag),
color_spec=CONST_PLOT_COLOR_SPEC,
+ marker='+',
)
+ #update the plotter
+ self.plotter.update()
def update(self):
#update the x axis
Modified: gnuradio/branches/developers/jblum/gr-wxglgui/src/python/plotter.py
===================================================================
--- gnuradio/branches/developers/jblum/gr-wxglgui/src/python/plotter.py
2008-07-01 15:21:21 UTC (rev 8766)
+++ gnuradio/branches/developers/jblum/gr-wxglgui/src/python/plotter.py
2008-07-01 20:06:15 UTC (rev 8767)
@@ -69,12 +69,13 @@
"""!
Respond to paint events, call update.
Initialize GL if this is the first paint event.
- """
+ """
self.SetCurrent()
#check if gl was initialized
if not self._gl_init_flag:
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB)
glClearColor(*BACKGROUND_COLOR_SPEC)
+ glEnableClientState(GL_VERTEX_ARRAY)
self._gl_init_flag = True
#check for a change in window size
if self._resized_flag:
@@ -210,24 +211,24 @@
# Draw Waveforms
##################################################
for channel in reversed(sorted(self.channels.keys())):
- samples, color_spec = self.channels[channel]
- glColor3f(*color_spec)
- if isinstance(samples, tuple): glBegin(GL_POINTS)
- else: glBegin(GL_LINE_STRIP)
+ samples, color_spec, marker = self.channels[channel]
num_samps = len(samples)
#use numpy to scale the waveform
+ x_scalar =
(self.width-self.padding_left-self.padding_right)
if isinstance(samples, tuple):
- x_scalar =
(self.width-self.padding_left-self.padding_right)
x_arr = x_scalar*(samples[0] -
self.x_min)/(self.x_max-self.x_min) + self.padding_left
samples = samples[1]
else:
- x_scalar =
(self.width-self.padding_left-self.padding_right)
x_arr = x_scalar*numpy.arange(0,
num_samps)/float(num_samps-1) + self.padding_left
y_scalar =
(self.height-self.padding_top-self.padding_bottom)
y_arr = y_scalar*(1 - (numpy.array(samples) -
self.y_min)/(self.y_max-self.y_min)) + self.padding_top
- #draw the lines
- for x, y in zip(x_arr, y_arr): glVertex3f(x, y, 0)
- glEnd()
+ #draw the points/lines
+ glColor3f(*color_spec)
+ points = zip(x_arr, y_arr)
+ if marker == '+':
+ points = numpy.concatenate([((x, y+4), (x,
y-4), (x+4, y), (x-4, y)) for x, y in points])
+ glVertexPointer(2, GL_FLOAT, 0, points)
+ glDrawArrays({None: GL_LINE_STRIP, '.': GL_POINTS, '+':
GL_LINES}[marker], 0, len(points))
def _draw_grid(self):
"""!
@@ -315,7 +316,7 @@
if self.legend:
for i, channel in
enumerate(sorted(self.channels.keys())):
x_off =
1.1*LEGEND_BOX_WIDTH*(len(self.channels) - i - 1) + LEGEND_BOX_WIDTH/2
- samples, color_spec = self.channels[channel]
+ color_spec = self.channels[channel][1]
#draw colored rectangle
glColor3f(*color_spec)
self._draw_rect(
@@ -392,14 +393,15 @@
glVertex3f(x, y+height, 0)
glEnd()
- def set_waveform(self, channel, samples, color_spec):
+ def set_waveform(self, channel, samples, color_spec, marker=None):
"""!
Set the waveform for a given channel.
@param channel the channel number
@param samples the waveform samples
@param color_spec the 3-tuple for line color
+ @param marker None for line
"""
- self.channels[channel] = samples, color_spec
+ self.channels[channel] = samples, color_spec, marker
if __name__ == '__main__':
app = wx.PySimpleApp()
Modified: gnuradio/branches/developers/jblum/gr-wxglgui/src/python/scopesink.py
===================================================================
--- gnuradio/branches/developers/jblum/gr-wxglgui/src/python/scopesink.py
2008-07-01 15:21:21 UTC (rev 8766)
+++ gnuradio/branches/developers/jblum/gr-wxglgui/src/python/scopesink.py
2008-07-01 20:06:15 UTC (rev 8767)
@@ -76,32 +76,7 @@
#begin control box
control_box.AddSpacer(2)
- control_box.Add(common.LabelText(self, 'Channel Menu'), 0,
wx.ALIGN_CENTER)
- control_box.AddSpacer(2)
- hbox = wx.BoxSizer(wx.HORIZONTAL)
- control_box.Add(hbox, 1, wx.EXPAND)
- #channel chooser drop down
- self.channel_chooser = wx.Choice(self, -1, choices=map(lambda
ch: "Ch%d"%ch, range(1, parent.num_inputs+1)))
- self.channel_chooser.Bind(wx.EVT_CHOICE, self._on_channel)
- hbox.Add(self.channel_chooser, 0, wx.EXPAND)
- #Run button
- control_box.AddSpacer(2)
- self.run_button = wx.Button(self, -1, '', style=wx.BU_EXACTFIT)
- self.run_button.Bind(wx.EVT_BUTTON, self._on_run)
- hbox.Add(self.run_button, 0, wx.EXPAND)
- #trigger check box
- self.trigger_check_box = wx.CheckBox(parent=self,
style=wx.CHK_2STATE, label="Trigger")
- self.trigger_check_box.Bind(wx.EVT_CHECKBOX,
self._on_set_trigger)
- control_box.Add(self.trigger_check_box, 0, wx.ALIGN_LEFT)
- #ac couple check box
- self.ac_couple_check_box = wx.CheckBox(parent=self,
style=wx.CHK_2STATE, label="AC Couple")
- self.ac_couple_check_box.Bind(wx.EVT_CHECKBOX,
self._on_ac_couple)
- control_box.Add(self.ac_couple_check_box, 0, wx.ALIGN_LEFT)
- #autorange check box
- self.autorange_check_box = wx.CheckBox(parent=self,
style=wx.CHK_2STATE, label="Autorange")
- self.autorange_check_box.Bind(wx.EVT_CHECKBOX,
self._on_autorange)
- control_box.Add(self.autorange_check_box, 0, wx.ALIGN_LEFT)
-
+
#trigger menu
control_box.AddSpacer(2)
control_box.Add(common.LabelText(self, 'Trigger Menu'), 0,
wx.ALIGN_CENTER)
@@ -109,6 +84,13 @@
#trigger mode
hbox = wx.BoxSizer(wx.HORIZONTAL)
control_box.Add(hbox, 1, wx.ALIGN_LEFT)
+ hbox.Add(wx.StaticText(self, -1, ' Channel '), 0,
wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
+ self.trigger_channel_chooser = wx.Choice(self, -1,
choices=map(lambda ch: "Ch%d"%ch, range(1, parent.num_inputs+1)))
+ self.trigger_channel_chooser.Bind(wx.EVT_CHOICE,
self._on_trigger_channel)
+ hbox.Add(self.trigger_channel_chooser, 0,
wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
+ #trigger mode
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ control_box.Add(hbox, 1, wx.ALIGN_LEFT)
hbox.Add(wx.StaticText(self, -1, ' Mode '), 0,
wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
self.trigger_mode_chooser = wx.Choice(self, -1, choices=[tm[0]
for tm in TRIGGER_MODES])
self.trigger_mode_chooser.Bind(wx.EVT_CHOICE,
self._on_trigger_mode)
@@ -147,14 +129,29 @@
#y axis ref lvl
hbox = wx.BoxSizer(wx.HORIZONTAL)
control_box.Add(hbox, 1, wx.ALIGN_LEFT)
- hbox.Add(wx.StaticText(self, -1, ' Ref Level '), 0,
wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
- self.ref_lvl_plus_button = wx.Button(self, -1, '+',
style=wx.BU_EXACTFIT)
- self.ref_lvl_plus_button.Bind(wx.EVT_BUTTON,
self._on_incr_ref_lvl)
- hbox.Add(self.ref_lvl_plus_button, 0, wx.ALIGN_CENTER_VERTICAL
| wx.ALIGN_LEFT)
- self.ref_lvl_minus_button = wx.Button(self, -1, ' - ',
style=wx.BU_EXACTFIT)
- self.ref_lvl_minus_button.Bind(wx.EVT_BUTTON,
self._on_decr_ref_lvl)
- hbox.Add(self.ref_lvl_minus_button, 0, wx.ALIGN_CENTER_VERTICAL
| wx.ALIGN_LEFT)
+ hbox.Add(wx.StaticText(self, -1, ' Y Offset '), 0,
wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
+ self.y_off_plus_button = wx.Button(self, -1, '+',
style=wx.BU_EXACTFIT)
+ self.y_off_plus_button.Bind(wx.EVT_BUTTON, self._on_incr_y_off)
+ hbox.Add(self.y_off_plus_button, 0, wx.ALIGN_CENTER_VERTICAL |
wx.ALIGN_LEFT)
+ self.y_off_minus_button = wx.Button(self, -1, ' - ',
style=wx.BU_EXACTFIT)
+ self.y_off_minus_button.Bind(wx.EVT_BUTTON, self._on_decr_y_off)
+ hbox.Add(self.y_off_minus_button, 0, wx.ALIGN_CENTER_VERTICAL |
wx.ALIGN_LEFT)
+ control_box.AddSpacer(2)
+ control_box.Add(common.LabelText(self, 'Channel Menu'), 0,
wx.ALIGN_CENTER)
+ #ac couple check box
+ self.ac_couple_check_box = wx.CheckBox(parent=self,
style=wx.CHK_2STATE, label="AC Couple")
+ self.ac_couple_check_box.Bind(wx.EVT_CHECKBOX,
self._on_ac_couple)
+ control_box.Add(self.ac_couple_check_box, 0, wx.ALIGN_LEFT)
+ #autorange check box
+ self.autorange_check_box = wx.CheckBox(parent=self,
style=wx.CHK_2STATE, label="Autorange")
+ self.autorange_check_box.Bind(wx.EVT_CHECKBOX,
self._on_autorange)
+ control_box.Add(self.autorange_check_box, 0, wx.ALIGN_LEFT)
+ #Run button
+ self.run_button = wx.Button(self, -1, '', style=wx.BU_EXACTFIT)
+ self.run_button.Bind(wx.EVT_BUTTON, self._on_run)
+ control_box.Add(self.run_button, 0, wx.EXPAND)
+
#end control box
control_box.AddSpacer(2)
#set sizer
@@ -166,51 +163,44 @@
"""!
Read the state of the scope plot settings and update the
control panel.
"""
- #update the channel chooser
- self.channel_chooser.SetSelection(self.parent.input_index)
- #update the trigger check box
- checked = self.parent.input_index == self.parent.trigger_index
- self.trigger_check_box.SetValue(checked)
- if checked: self.trigger_check_box.Disable()
- else: self.trigger_check_box.Enable()
#update the ac couple check box
-
self.ac_couple_check_box.SetValue(self.parent.ac_couple[self.parent.input_index])
+ self.ac_couple_check_box.SetValue(self.parent.ac_couple)
#update the autorange check box
- self.autorange_check_box.SetValue(self.parent.autorange_index
== self.parent.input_index)
- #update trigger mode and level chooser
-
self.trigger_level_chooser.SetSelection(self.parent.trigger_level_index)
+ self.autorange_check_box.SetValue(self.parent.autorange)
+ #update trigger menu
+
self.trigger_channel_chooser.SetSelection(self.parent.trigger_channel_index)
self.trigger_mode_chooser.SetSelection(self.parent.trigger_mode_index)
+
self.trigger_level_chooser.SetSelection(self.parent.trigger_level_index)
#update the run/stop button
if self.parent.running: self.run_button.SetLabel('Stop')
else: self.run_button.SetLabel('Run')
#update the y adj buttons
- if self.parent.autorange_index is None:
- self.y_plus_button.Enable()
- self.y_minus_button.Enable()
- self.ref_lvl_plus_button.Enable()
- self.ref_lvl_minus_button.Enable()
- else:
+ if self.parent.autorange:
self.y_plus_button.Disable()
self.y_minus_button.Disable()
- self.ref_lvl_plus_button.Disable()
- self.ref_lvl_minus_button.Disable()
+ self.y_off_plus_button.Disable()
+ self.y_off_minus_button.Disable()
+ else:
+ self.y_plus_button.Enable()
+ self.y_minus_button.Enable()
+ self.y_off_plus_button.Enable()
+ self.y_off_minus_button.Enable()
##################################################
# Event handlers
##################################################
def _on_channel(self, event):
self.parent.set_input_index(self.channel_chooser.GetSelection())
- def _on_ac_couple(self, event):
self.parent.set_ac_couple(self.parent.input_index, event.IsChecked())
- def _on_autorange(self, event):
self.parent.set_autorange(self.parent.input_index, event.IsChecked())
+ def _on_ac_couple(self, event):
self.parent.set_ac_couple(event.IsChecked())
+ def _on_autorange(self, event):
self.parent.set_autorange(event.IsChecked())
+ def _on_trigger_channel(self, event):
self.parent.set_trigger_channel_index(self.trigger_channel_chooser.GetSelection())
def _on_trigger_mode(self, event):
self.parent.set_trigger_mode_index(self.trigger_mode_chooser.GetSelection())
def _on_trigger_level(self, event):
self.parent.set_trigger_level_index(self.trigger_level_chooser.GetSelection())
- def _on_set_trigger(self, event):
- if event.IsChecked():
self.parent.set_trigger_index(self.parent.input_index)
def _on_incr_x_divs(self, event):
self.parent.set_x_per_div(common.get_clean_incr(self.parent.x_per_div))
def _on_decr_x_divs(self, event):
self.parent.set_x_per_div(common.get_clean_decr(self.parent.x_per_div))
def _on_incr_y_divs(self, event):
self.parent.set_y_per_div(common.get_clean_incr(self.parent.y_per_div))
def _on_decr_y_divs(self, event):
self.parent.set_y_per_div(common.get_clean_decr(self.parent.y_per_div))
- def _on_incr_ref_lvl(self, event):
self.parent.set_y_off(self.parent.y_off + self.parent.y_per_div)
- def _on_decr_ref_lvl(self, event):
self.parent.set_y_off(self.parent.y_off - self.parent.y_per_div)
+ def _on_incr_y_off(self, event):
self.parent.set_y_off(self.parent.y_off + self.parent.y_per_div)
+ def _on_decr_y_off(self, event):
self.parent.set_y_off(self.parent.y_off - self.parent.y_per_div)
def _on_run(self, event): self.parent.set_run(not self.parent.running)
##################################################
@@ -236,13 +226,12 @@
self.running = True
self.num_inputs = num_inputs
self.sample_rate = sample_rate
- self.ac_couple = [ac_couple]*num_inputs
- if y_per_div is None: self.autorange_index = 0
- else: self.autorange_index = None
+ self.ac_couple = ac_couple
+ self.autorange = y_per_div is None
self.autorange_ts = 0
self.input_index = 0
#triggering
- self.trigger_index = 0
+ self.trigger_channel_index = 0
self.trigger_mode_index = 1
self.trigger_level_index = 0
#x grid settings
@@ -284,27 +273,30 @@
self.update()
if not self.running: return
if self.frame_counter == 0: #decimate
+ #trigger level (must do before ac coupling)
+ samples = sampleses[self.trigger_level_index]
+ trigger_level =
TRIGGER_LEVELS[self.trigger_level_index][1]
+ if trigger_level is None:
self.scope.set_trigger_level_auto()
+ else:
self.scope.set_trigger_level(trigger_level*(numpy.max(samples)-numpy.min(samples))/2
+ numpy.average(samples))
+ #ac coupling
+ if self.ac_couple:
+ sampleses = [samples - numpy.average(samples)
for samples in sampleses]
+ #autorange
+ if self.autorange and time.time() - self.autorange_ts >
AUTORANGE_UPDATE_RATE:
+ bounds = [common.get_min_max(samples) for
samples in sampleses]
+ y_min = min(*[bound[0] for bound in bounds])
+ y_max = max(*[bound[1] for bound in bounds])
+ #adjust the y per div
+ y_per_div =
common.get_clean_num((y_max-y_min)/self.y_divs)
+ if self.y_per_div != y_per_div:
self.set_y_per_div(y_per_div)
+ #adjust the y offset
+ y_off =
self.y_per_div*round((y_max+y_min)/2/self.y_per_div)
+ if self.y_off != y_off: self.set_y_off(y_off)
+ self.autorange_ts = time.time()
+ #plot each waveform
for i, samples in enumerate(sampleses):
#number of samples to scale to the screen
num_samps =
int(self.x_per_div*self.x_divs*self.sample_rate)
- #trigger level (must do before ac coupling)
- if i == self.trigger_index:
- trigger_level =
TRIGGER_LEVELS[self.trigger_level_index][1]
- if trigger_level is None:
self.scope.set_trigger_level_auto()
- else:
self.scope.set_trigger_level(trigger_level*(numpy.max(samples)-numpy.min(samples))/2
+ numpy.average(samples))
- #ac coupling
- if self.ac_couple[i]: samples = samples -
numpy.average(samples)
- #autorange
- if self.autorange_index == i and \
- time.time() - self.autorange_ts >
AUTORANGE_UPDATE_RATE:
- min, max = common.get_min_max(samples)
- #adjust the y per div
- y_per_div =
common.get_clean_num((max-min)/self.y_divs)
- if self.y_per_div != y_per_div:
self.set_y_per_div(y_per_div)
- #adjust the y offset
- y_off =
self.y_per_div*round((max+min)/2/self.y_per_div)
- if self.y_off != y_off:
self.set_y_off(y_off)
- self.autorange_ts = time.time()
#handle num samps out of bounds
while num_samps > len(samples): samples =
numpy.concatenate((samples, samples))
if num_samps < 2: num_samps = 0
@@ -323,7 +315,7 @@
self.decim = max(1,
int(self.sample_rate/self.scope.get_samples_per_output_record()/self.frame_rate))
#update the scope
if self._init: #HACK avoid segfaults, only set after a sample
has arrived
- self.scope.set_trigger_channel(self.trigger_index)
+
self.scope.set_trigger_channel(self.trigger_channel_index)
self.scope.set_trigger_mode(TRIGGER_MODES[self.trigger_mode_index][1])
self.scope.set_sample_rate(self.sample_rate)
#update the x axis
@@ -364,8 +356,8 @@
def set_y_off(self, y_off):
self.y_off = y_off
self.update()
- def set_input_index(self, input_index):
- self.input_index = input_index
+ def set_trigger_channel_index(self, trigger_channel_index):
+ self.trigger_channel_index = trigger_channel_index
self.update()
def set_trigger_mode_index(self, trigger_mode_index):
self.trigger_mode_index = trigger_mode_index
@@ -379,13 +371,11 @@
def set_run(self, running):
self.running = running
self.update()
- def set_ac_couple(self, channel_index, ac_couple):
- self.ac_couple[channel_index] = ac_couple
+ def set_ac_couple(self, ac_couple):
+ self.ac_couple = ac_couple
self.update()
- def set_autorange(self, channel_index, autorange):
- if autorange: self.autorange_index = channel_index
- elif not autorange and self.autorange_index == channel_index:
- self.autorange_index = None
+ def set_autorange(self, autorange):
+ self.autorange = autorange
self.update()
def set_sample_rate(self, sample_rate):
self.sample_rate = sample_rate
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r8767 - gnuradio/branches/developers/jblum/gr-wxglgui/src/python,
jblum <=