Added option for pulse matched filtering
Pulse matched filtering places a boxcar filter upstream of the averager and preamble detector. The filter length is equivalent to the number of samples in one Mode S chip (0.5us). This technique enhances operation when using sample rates > 4Msps. * rx_path.py now takes 'use_pmf', defaults to False * modes_rx has new CLI option '-p' or '--pmf' to turn on PMF * modes_gui has new checkbox on Setup tab
This commit is contained in:
parent
1adbf81950
commit
686078bf72
@ -239,6 +239,7 @@ class mainwindow(QtGui.QMainWindow):
|
|||||||
options["gain"] = float(self.ui.line_gain.text())
|
options["gain"] = float(self.ui.line_gain.text())
|
||||||
options["threshold"] = float(self.ui.line_threshold.text())
|
options["threshold"] = float(self.ui.line_threshold.text())
|
||||||
options["filename"] = str(self.ui.line_inputfile.text())
|
options["filename"] = str(self.ui.line_inputfile.text())
|
||||||
|
options["pmf"] = self.ui.check_pmf.checkState()
|
||||||
|
|
||||||
self.fg = adsb_rx_block(options, self.queue) #create top RX block
|
self.fg = adsb_rx_block(options, self.queue) #create top RX block
|
||||||
self.runner = top_block_runner(self.fg) #spawn new thread to do RX
|
self.runner = top_block_runner(self.fg) #spawn new thread to do RX
|
||||||
@ -409,7 +410,7 @@ class adsb_rx_block (gr.top_block):
|
|||||||
else:
|
else:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
self.rx_path = air_modes.rx_path(rate, options["threshold"], queue)
|
self.rx_path = air_modes.rx_path(rate, options["threshold"], queue, options["pmf"])
|
||||||
|
|
||||||
if use_resampler:
|
if use_resampler:
|
||||||
self.lpfiltcoeffs = gr.firdes.low_pass(1, 5*3.2e6, 1.6e6, 300e3)
|
self.lpfiltcoeffs = gr.firdes.low_pass(1, 5*3.2e6, 1.6e6, 300e3)
|
||||||
|
@ -110,7 +110,7 @@ class adsb_rx_block (gr.top_block):
|
|||||||
if options.output_all :
|
if options.output_all :
|
||||||
pass_all = 1
|
pass_all = 1
|
||||||
|
|
||||||
self.rx_path = air_modes.rx_path(rate, options.threshold, queue)
|
self.rx_path = air_modes.rx_path(rate, options.threshold, queue, options.pmf)
|
||||||
|
|
||||||
if use_resampler:
|
if use_resampler:
|
||||||
self.lpfiltcoeffs = gr.firdes.low_pass(1, 5*3.2e6, 1.6e6, 300e3)
|
self.lpfiltcoeffs = gr.firdes.low_pass(1, 5*3.2e6, 1.6e6, 300e3)
|
||||||
@ -163,6 +163,8 @@ if __name__ == '__main__':
|
|||||||
help="FlightGear server to send aircraft data, in format host:port")
|
help="FlightGear server to send aircraft data, in format host:port")
|
||||||
parser.add_option("-d","--rtlsdr", action="store_true", default=False,
|
parser.add_option("-d","--rtlsdr", action="store_true", default=False,
|
||||||
help="Use RTLSDR dongle instead of UHD source")
|
help="Use RTLSDR dongle instead of UHD source")
|
||||||
|
parser.add_option("-p","--pmf", action="store_true", default=False,
|
||||||
|
help="Use pulse matched filtering")
|
||||||
|
|
||||||
(options, args) = parser.parse_args()
|
(options, args) = parser.parse_args()
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ import air_modes_swig
|
|||||||
|
|
||||||
class rx_path(gr.hier_block2):
|
class rx_path(gr.hier_block2):
|
||||||
|
|
||||||
def __init__(self, rate, threshold, queue):
|
def __init__(self, rate, threshold, queue, use_pmf=False):
|
||||||
gr.hier_block2.__init__(self, "modes_rx_path",
|
gr.hier_block2.__init__(self, "modes_rx_path",
|
||||||
gr.io_signature(1, 1, gr.sizeof_gr_complex),
|
gr.io_signature(1, 1, gr.sizeof_gr_complex),
|
||||||
gr.io_signature(0,0,0))
|
gr.io_signature(0,0,0))
|
||||||
@ -32,12 +32,20 @@ class rx_path(gr.hier_block2):
|
|||||||
self._rate = int(rate)
|
self._rate = int(rate)
|
||||||
self._threshold = threshold
|
self._threshold = threshold
|
||||||
self._queue = queue
|
self._queue = queue
|
||||||
|
self._spc = int(rate/2e6)
|
||||||
|
|
||||||
# Convert incoming I/Q baseband to amplitude
|
# Convert incoming I/Q baseband to amplitude
|
||||||
self._demod = gr.complex_to_mag()
|
self._demod = gr.complex_to_mag()
|
||||||
|
self._bb = self._demod
|
||||||
|
|
||||||
|
# Pulse matched filter for 0.5us pulses
|
||||||
|
if use_pmf:
|
||||||
|
self._pmf = gr.moving_average_ff(self._spc, 1.0/self._spc, self._rate)
|
||||||
|
self.connect(self._demod, self._pmf)
|
||||||
|
self._bb = self._pmf
|
||||||
|
|
||||||
# Establish baseline amplitude (noise, interference)
|
# Establish baseline amplitude (noise, interference)
|
||||||
self._avg = gr.moving_average_ff(100, 1.0/100, 400) # FIXME
|
self._avg = gr.moving_average_ff(48*self._spc, 1.0/(48*self._spc), self._rate) # 3 preambles
|
||||||
|
|
||||||
# Synchronize to Mode-S preamble
|
# Synchronize to Mode-S preamble
|
||||||
self._sync = air_modes_swig.modes_preamble(self._rate, self._threshold)
|
self._sync = air_modes_swig.modes_preamble(self._rate, self._threshold)
|
||||||
@ -45,6 +53,8 @@ class rx_path(gr.hier_block2):
|
|||||||
# Slice Mode-S bits and send to message queue
|
# Slice Mode-S bits and send to message queue
|
||||||
self._slicer = air_modes_swig.modes_slicer(self._rate, self._queue)
|
self._slicer = air_modes_swig.modes_slicer(self._rate, self._queue)
|
||||||
|
|
||||||
self.connect(self, self._demod, (self._sync, 0))
|
# Wire up the flowgraph
|
||||||
self.connect(self._demod, self._avg, (self._sync, 1))
|
self.connect(self, self._demod)
|
||||||
|
self.connect(self._bb, (self._sync, 0))
|
||||||
|
self.connect(self._bb, self._avg, (self._sync, 1))
|
||||||
self.connect(self._sync, self._slicer)
|
self.connect(self._sync, self._slicer)
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>1</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="tab">
|
<widget class="QWidget" name="tab">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
@ -147,7 +147,7 @@
|
|||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>1</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="page_rf">
|
<widget class="QWidget" name="page_rf">
|
||||||
<widget class="QComboBox" name="combo_ant">
|
<widget class="QComboBox" name="combo_ant">
|
||||||
@ -234,10 +234,6 @@
|
|||||||
<string>Filename</string>
|
<string>Filename</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<zorder>line_inputfile</zorder>
|
|
||||||
<zorder>label_13</zorder>
|
|
||||||
<zorder>combo_rate</zorder>
|
|
||||||
<zorder>label_27</zorder>
|
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
@ -460,6 +456,19 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QCheckBox" name="check_pmf">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>20</x>
|
||||||
|
<y>210</y>
|
||||||
|
<width>221</width>
|
||||||
|
<height>22</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Use Pulse Matched Filtering</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="dashboard">
|
<widget class="QWidget" name="dashboard">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
|
Loading…
Reference in New Issue
Block a user