[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] r10919 - gnuradio/trunk/gr-qtgui/src/python
From: |
trondeau |
Subject: |
[Commit-gnuradio] r10919 - gnuradio/trunk/gr-qtgui/src/python |
Date: |
Sun, 26 Apr 2009 15:09:20 -0600 (MDT) |
Author: trondeau
Date: 2009-04-26 15:09:20 -0600 (Sun, 26 Apr 2009)
New Revision: 10919
Modified:
gnuradio/trunk/gr-qtgui/src/python/qt_digital.py
gnuradio/trunk/gr-qtgui/src/python/qt_digital_window.ui
Log:
Improving digital GUI analysis tool. Adding receiver carrier and timing
recovery loop and ability to control the some of the receiver's parameters.
Modified: gnuradio/trunk/gr-qtgui/src/python/qt_digital.py
===================================================================
--- gnuradio/trunk/gr-qtgui/src/python/qt_digital.py 2009-04-26 20:21:02 UTC
(rev 10918)
+++ gnuradio/trunk/gr-qtgui/src/python/qt_digital.py 2009-04-26 21:09:20 UTC
(rev 10919)
@@ -2,6 +2,7 @@
from gnuradio import gr, blks2
from gnuradio.qtgui import qtgui
+from gnuradio import eng_notation
from PyQt4 import QtGui, QtCore
import sys, sip
import scipy
@@ -14,98 +15,169 @@
sys.exit(1)
class dialog_box(QtGui.QMainWindow):
- def __init__(self, snkTx, snkRx, channel, parent=None):
+ def __init__(self, snkTx, snkRx, fg, parent=None):
QtGui.QWidget.__init__(self, parent)
self.gui = Ui_DigitalWindow()
self.gui.setupUi(self)
- self.channel = channel
+ self.fg = fg
+ self.set_sample_rate(self.fg.sample_rate())
+
+ self.set_snr(self.fg.snr())
+ self.set_frequency(self.fg.frequency_offset())
+ self.set_time_offset(self.fg.timing_offset())
+
+ self.set_gain_mu(self.fg.rx_gain_mu())
+ self.set_alpha(self.fg.rx_alpha())
+
# Add the qtsnk widgets to the hlayout box
self.gui.sinkLayout.addWidget(snkTx)
self.gui.sinkLayout.addWidget(snkRx)
# Connect up some signals
- self.connect(self.gui.noiseEdit, QtCore.SIGNAL("editingFinished()"),
- self.noiseEditText)
+ self.connect(self.gui.sampleRateEdit,
QtCore.SIGNAL("editingFinished()"),
+ self.sampleRateEditText)
+
+ self.connect(self.gui.snrEdit, QtCore.SIGNAL("editingFinished()"),
+ self.snrEditText)
self.connect(self.gui.freqEdit, QtCore.SIGNAL("editingFinished()"),
self.freqEditText)
self.connect(self.gui.timeEdit, QtCore.SIGNAL("editingFinished()"),
self.timeEditText)
-
- def set_noise(self, noise):
- self.noise = noise
- self.gui.noiseEdit.setText(QtCore.QString("%1").arg(self.noise))
- def set_frequency(self, freq):
- self.freq = freq
- self.gui.freqEdit.setText(QtCore.QString("%1").arg(self.freq))
+ self.connect(self.gui.gainMuEdit, QtCore.SIGNAL("editingFinished()"),
+ self.gainMuEditText)
+ self.connect(self.gui.alphaEdit, QtCore.SIGNAL("editingFinished()"),
+ self.alphaEditText)
+
+ # Accessor functions for Gui to manipulate system parameters
+ def set_sample_rate(self, sr):
+ ssr = eng_notation.num_to_str(sr)
+ self.gui.sampleRateEdit.setText(QtCore.QString("%1").arg(ssr))
+
+ def sampleRateEditText(self):
+ try:
+ rate = self.gui.sampleRateEdit.text().toAscii()
+ srate = eng_notation.str_to_num(rate)
+ self.fg.set_sample_rate(srate)
+ except RuntimeError:
+ pass
+
+
+ # Accessor functions for Gui to manipulate channel model
+ def set_snr(self, snr):
+ self.gui.snrEdit.setText(QtCore.QString("%1").arg(snr))
+
+ def set_frequency(self, fo):
+ self.gui.freqEdit.setText(QtCore.QString("%1").arg(fo))
+
def set_time_offset(self, to):
- self.timing_offset = to
- self.gui.timeEdit.setText(QtCore.QString("%1").arg(self.timing_offset))
+ self.gui.timeEdit.setText(QtCore.QString("%1").arg(to))
- def noiseEditText(self):
+ def snrEditText(self):
try:
- noise = self.gui.noiseEdit.text().toDouble()[0]
- self.channel.set_noise_voltage(noise)
-
- self.noise = noise
+ snr = self.gui.snrEdit.text().toDouble()[0]
+ self.fg.set_snr(snr)
except RuntimeError:
pass
def freqEditText(self):
try:
freq = self.gui.freqEdit.text().toDouble()[0]
- self.channel.set_frequency_offset(freq)
-
- self.freq = freq
+ self.fg.set_frequency_offset(freq)
except RuntimeError:
pass
def timeEditText(self):
try:
to = self.gui.timeEdit.text().toDouble()[0]
- self.channel.set_timing_offset(to)
+ self.fg.set_timing_offset(to)
+ except RuntimeError:
+ pass
- self.timing_offset = to
+
+ # Accessor functions for Gui to manipulate receiver parameters
+ def set_gain_mu(self, gain):
+ self.gui.gainMuEdit.setText(QtCore.QString("%1").arg(gain))
+
+ def set_alpha(self, alpha):
+ self.gui.alphaEdit.setText(QtCore.QString("%1").arg(alpha))
+
+ def alphaEditText(self):
+ try:
+ alpha = self.gui.alphaEdit.text().toDouble()[0]
+ self.fg.set_rx_alpha(alpha)
except RuntimeError:
pass
+ def gainMuEditText(self):
+ try:
+ gain = self.gui.gainMuEdit.text().toDouble()[0]
+ self.fg.set_rx_gain_mu(gain)
+ except RuntimeError:
+ pass
+
class my_top_block(gr.top_block):
def __init__(self):
gr.top_block.__init__(self)
self.qapp = QtGui.QApplication(sys.argv)
- sps = 2
- excess_bw = 0.35
- gray_code = True
+ self._sample_rate = 200e3
+
+ self.sps = 2
+ self.excess_bw = 0.35
+ self.gray_code = True
fftsize = 2048
- data = scipy.random.randint(0, 255, 1000)
- src = gr.vector_source_b(data, True)
- mod = blks2.dqpsk_mod(sps, excess_bw, gray_code, False, False)
+ self.data = scipy.random.randint(0, 255, 1000)
+ self.src = gr.vector_source_b(self.data, True)
+ self.mod = blks2.dqpsk_mod(self.sps, self.excess_bw, self.gray_code,
False, False)
- rrctaps = gr.firdes.root_raised_cosine(1, sps, 1, excess_bw, 21)
- rx_rrc = gr.fir_filter_ccf(sps, rrctaps)
+ self.rrctaps = gr.firdes.root_raised_cosine(1, self.sps, 1,
self.excess_bw, 21)
+ self.rx_rrc = gr.fir_filter_ccf(1, self.rrctaps)
- noise = 1e-7
- fo = 1e-6
- to = 1.0
- channel = gr.channel_model(noise, fo, to)
- thr = gr.throttle(gr.sizeof_gr_complex, 10*fftsize)
+ # Set up the carrier & clock recovery parameters
+ self.arity = 4
+ self.mu = 0.5
+ self.gain_mu = 0.05
+ self.omega = self.sps
+ self.gain_omega = .25 * self.gain_mu * self.gain_mu
+ self.omega_rel_lim = 0.05
+
+ self.alpha = 0.15
+ self.beta = 0.25 * self.alpha * self.alpha
+ self.fmin = -1000/self.sample_rate()
+ self.fmax = 1000/self.sample_rate()
+
+ self.receiver = gr.mpsk_receiver_cc(self.arity, 0,
+ self.alpha, self.beta,
+ self.fmin, self.fmax,
+ self.mu, self.gain_mu,
+ self.omega, self.gain_omega,
+ self.omega_rel_lim)
+
+
+ self.snr_dB = 15
+ noise = self.get_noise_voltage(self.snr_dB)
+ self.fo = 100/self.sample_rate()
+ self.to = 1.0
+ self.channel = gr.channel_model(noise, self.fo, self.to)
+
+ self.thr = gr.throttle(gr.sizeof_char, 10*fftsize)
self.snk_tx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS,
-1/2, 1/2,
"Tx", True, True, False, True, True)
self.snk_rx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS,
-1/2, 1/2,
"Rx", True, True, False, True, True)
- self.connect(src, mod, channel, self.snk_tx)
- self.connect(channel, rx_rrc, thr, self.snk_rx)
+ self.connect(self.src, self.thr, self.mod, self.channel, self.snk_tx)
+ self.connect(self.channel, self.rx_rrc, self.receiver, self.snk_rx)
pyTxQt = self.snk_tx.pyqwidget()
pyTx = sip.wrapinstance(pyTxQt, QtGui.QWidget)
@@ -113,14 +185,76 @@
pyRxQt = self.snk_rx.pyqwidget()
pyRx = sip.wrapinstance(pyRxQt, QtGui.QWidget)
- self.main_box = dialog_box(pyTx, pyRx, channel);
- self.main_box.set_noise(noise)
- self.main_box.set_frequency(fo)
- self.main_box.set_time_offset(to)
+ self.main_box = dialog_box(pyTx, pyRx, self);
self.main_box.show()
+ def get_noise_voltage(self, SNR):
+ S = 0 # dBm, assuming signal power
normalized
+ N = S - SNR # dBm
+ npwr = pow(10.0, N/10.0) # ratio
+ nv = scipy.sqrt(npwr * self.sps) # convert the noise voltage
+ return nv
+
+
+ # System Parameters
+ def sample_rate(self):
+ return self._sample_rate
+ def set_sample_rate(self, sr):
+ self._sample_rate = sr
+
+
+ # Channel Model Parameters
+ def snr(self):
+ return self.snr_dB
+
+ def set_snr(self, snr):
+ self.snr_dB = snr
+ noise = self.get_noise_voltage(self.snr_dB)
+ self.channel.set_noise_voltage(noise)
+
+ def frequency_offset(self):
+ return self.fo * self.sample_rate()
+
+ def set_frequency_offset(self, fo):
+ self.fo = fo / self.sample_rate()
+ self.channel.set_frequency_offset(self.fo)
+
+ def timing_offset(self):
+ return self.to
+
+ def set_timing_offset(self, to):
+ self.to = to
+ self.channel.set_timing_offset(self.to)
+
+
+ # Receiver Parameters
+ def rx_gain_mu(self):
+ return self.gain_mu
+
+ def rx_gain_omega(self):
+ return self.gain_omega
+
+ def set_rx_gain_mu(self, gain):
+ self.gain_mu = gain
+ self.gain_omega = .25 * self.gain_mu * self.gain_mu
+ self.receiver.set_gain_mu(self.gain_mu)
+ self.receiver.set_gain_omega(self.gain_omega)
+
+ def rx_alpha(self):
+ return self.alpha
+
+ def rx_beta(self):
+ return self.beta
+
+ def set_rx_alpha(self, alpha):
+ self.alpha = alpha
+ self.beta = .25 * self.alpha * self.alpha
+ self.receiver.set_alpha(self.alpha)
+ self.receiver.set_beta(self.beta)
+
+
if __name__ == "__main__":
tb = my_top_block();
tb.start()
Modified: gnuradio/trunk/gr-qtgui/src/python/qt_digital_window.ui
===================================================================
--- gnuradio/trunk/gr-qtgui/src/python/qt_digital_window.ui 2009-04-26
20:21:02 UTC (rev 10918)
+++ gnuradio/trunk/gr-qtgui/src/python/qt_digital_window.ui 2009-04-26
21:09:20 UTC (rev 10919)
@@ -1,155 +1,264 @@
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
<class>DigitalWindow</class>
- <widget class="QMainWindow" name="DigitalWindow" >
- <property name="geometry" >
+ <widget class="QMainWindow" name="DigitalWindow">
+ <property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1236</width>
- <height>655</height>
+ <height>739</height>
</rect>
</property>
- <property name="windowTitle" >
+ <property name="windowTitle">
<string>MainWindow</string>
</property>
- <widget class="QWidget" name="centralwidget" >
- <widget class="QLineEdit" name="noiseEdit" >
- <property name="geometry" >
+ <widget class="QWidget" name="centralwidget">
+ <widget class="QPushButton" name="closeButton">
+ <property name="geometry">
<rect>
- <x>120</x>
- <y>520</y>
- <width>113</width>
- <height>23</height>
+ <x>1120</x>
+ <y>650</y>
+ <width>101</width>
+ <height>31</height>
</rect>
</property>
+ <property name="text">
+ <string>Close</string>
+ </property>
</widget>
- <widget class="QLabel" name="noiseLabel" >
- <property name="geometry" >
+ <widget class="QFrame" name="sinkFrame">
+ <property name="geometry">
<rect>
<x>10</x>
- <y>520</y>
- <width>111</width>
- <height>20</height>
+ <y>10</y>
+ <width>1221</width>
+ <height>501</height>
</rect>
</property>
- <property name="text" >
- <string>Noise Amplitude</string>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
</property>
- </widget>
- <widget class="QPushButton" name="closeButton" >
- <property name="geometry" >
- <rect>
- <x>260</x>
- <y>580</y>
- <width>80</width>
- <height>27</height>
- </rect>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
</property>
- <property name="text" >
- <string>Close</string>
- </property>
+ <widget class="QWidget" name="horizontalLayoutWidget">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>10</y>
+ <width>1201</width>
+ <height>481</height>
+ </rect>
+ </property>
+ <layout class="QHBoxLayout" name="sinkLayout"/>
+ </widget>
</widget>
- <widget class="QLineEdit" name="freqEdit" >
- <property name="geometry" >
+ <widget class="QGroupBox" name="channelModeBox">
+ <property name="geometry">
<rect>
- <x>120</x>
- <y>550</y>
- <width>113</width>
- <height>23</height>
+ <x>290</x>
+ <y>520</y>
+ <width>291</width>
+ <height>161</height>
</rect>
</property>
- </widget>
- <widget class="QLineEdit" name="timeEdit" >
- <property name="geometry" >
- <rect>
- <x>120</x>
- <y>580</y>
- <width>113</width>
- <height>23</height>
- </rect>
+ <property name="title">
+ <string>Channel Model Parameters</string>
</property>
+ <widget class="QLabel" name="timeLabel">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>90</y>
+ <width>101</width>
+ <height>17</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Timing Offset</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" name="timeEdit">
+ <property name="geometry">
+ <rect>
+ <x>160</x>
+ <y>90</y>
+ <width>113</width>
+ <height>23</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QLineEdit" name="snrEdit">
+ <property name="geometry">
+ <rect>
+ <x>160</x>
+ <y>30</y>
+ <width>113</width>
+ <height>23</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QLabel" name="snrLabel">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>30</y>
+ <width>111</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>SNR (dB)</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" name="freqEdit">
+ <property name="geometry">
+ <rect>
+ <x>160</x>
+ <y>60</y>
+ <width>113</width>
+ <height>23</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QLabel" name="freqLabel">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>60</y>
+ <width>141</width>
+ <height>17</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Frequency Offset (Hz)</string>
+ </property>
+ </widget>
</widget>
- <widget class="QLabel" name="freqLabel" >
- <property name="geometry" >
+ <widget class="QGroupBox" name="rxBox">
+ <property name="geometry">
<rect>
- <x>10</x>
- <y>550</y>
- <width>101</width>
- <height>17</height>
+ <x>590</x>
+ <y>520</y>
+ <width>251</width>
+ <height>161</height>
</rect>
</property>
- <property name="text" >
- <string>Frequency Offset</string>
+ <property name="title">
+ <string>Receiver Parameters</string>
</property>
+ <widget class="QLineEdit" name="gainMuEdit">
+ <property name="geometry">
+ <rect>
+ <x>120</x>
+ <y>30</y>
+ <width>113</width>
+ <height>23</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QLabel" name="gainMuLabel">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>30</y>
+ <width>111</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Gain mu</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" name="alphaEdit">
+ <property name="geometry">
+ <rect>
+ <x>120</x>
+ <y>60</y>
+ <width>113</width>
+ <height>23</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QLabel" name="alphaLabel">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>60</y>
+ <width>111</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Alpha</string>
+ </property>
+ </widget>
</widget>
- <widget class="QLabel" name="timeLabel" >
- <property name="geometry" >
+ <widget class="QGroupBox" name="sysBox">
+ <property name="geometry">
<rect>
- <x>10</x>
- <y>580</y>
- <width>101</width>
- <height>17</height>
+ <x>20</x>
+ <y>520</y>
+ <width>261</width>
+ <height>161</height>
</rect>
</property>
- <property name="text" >
- <string>Timing Offset</string>
+ <property name="title">
+ <string>System Parameters</string>
</property>
- </widget>
- <widget class="QFrame" name="sinkFrame" >
- <property name="geometry" >
- <rect>
- <x>10</x>
- <y>10</y>
- <width>1221</width>
- <height>501</height>
- </rect>
- </property>
- <property name="frameShape" >
- <enum>QFrame::StyledPanel</enum>
- </property>
- <property name="frameShadow" >
- <enum>QFrame::Raised</enum>
- </property>
- <widget class="QWidget" name="horizontalLayoutWidget" >
- <property name="geometry" >
+ <widget class="QLineEdit" name="sampleRateEdit">
+ <property name="geometry">
<rect>
+ <x>140</x>
+ <y>30</y>
+ <width>113</width>
+ <height>23</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QLabel" name="sampleRateLabel">
+ <property name="geometry">
+ <rect>
<x>10</x>
- <y>10</y>
- <width>1201</width>
- <height>481</height>
+ <y>30</y>
+ <width>121</width>
+ <height>20</height>
</rect>
</property>
- <layout class="QHBoxLayout" name="sinkLayout" />
+ <property name="text">
+ <string>Sample Rate (sps)</string>
+ </property>
</widget>
</widget>
</widget>
- <widget class="QMenuBar" name="menubar" >
- <property name="geometry" >
+ <widget class="QMenuBar" name="menubar">
+ <property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1236</width>
- <height>22</height>
+ <height>25</height>
</rect>
</property>
- <widget class="QMenu" name="menuFile" >
- <property name="title" >
+ <widget class="QMenu" name="menuFile">
+ <property name="title">
<string>&File</string>
</property>
- <addaction name="actionExit" />
+ <addaction name="actionExit"/>
</widget>
- <addaction name="menuFile" />
+ <addaction name="menuFile"/>
</widget>
- <widget class="QStatusBar" name="statusbar" />
- <action name="actionExit" >
- <property name="text" >
+ <widget class="QStatusBar" name="statusbar"/>
+ <action name="actionExit">
+ <property name="text">
<string>E&xit</string>
</property>
</action>
</widget>
<tabstops>
<tabstop>closeButton</tabstop>
- <tabstop>noiseEdit</tabstop>
+ <tabstop>snrEdit</tabstop>
<tabstop>freqEdit</tabstop>
<tabstop>timeEdit</tabstop>
</tabstops>
@@ -161,11 +270,11 @@
<receiver>DigitalWindow</receiver>
<slot>close()</slot>
<hints>
- <hint type="sourcelabel" >
+ <hint type="sourcelabel">
<x>322</x>
<y>623</y>
</hint>
- <hint type="destinationlabel" >
+ <hint type="destinationlabel">
<x>66</x>
<y>561</y>
</hint>
@@ -177,11 +286,11 @@
<receiver>DigitalWindow</receiver>
<slot>close()</slot>
<hints>
- <hint type="sourcelabel" >
+ <hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
- <hint type="destinationlabel" >
+ <hint type="destinationlabel">
<x>617</x>
<y>327</y>
</hint>
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r10919 - gnuradio/trunk/gr-qtgui/src/python,
trondeau <=