gr-air-modes/python/rx_path.py

132 lines
4.9 KiB
Python

#
# Copyright 2012, 2013 Corgan Labs, Nick Foster
#
# This file is part of gr-air-modes
#
# gr-air-modes is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# gr-air-modes is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with gr-air-modes; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
from gnuradio import gr, blocks, filter
import air_modes_swig
class rx_path(gr.hier_block2):
def __init__(self, rate, threshold, queue, use_pmf=False, use_dcblock=False):
gr.hier_block2.__init__(self, "modes_rx_path",
gr.io_signature(1, 1, gr.sizeof_gr_complex),
gr.io_signature(0,0,0))
self._rate = int(rate)
self._threshold = threshold
self._queue = queue
self._spc = int(rate/2e6)
# Convert incoming I/Q baseband to amplitude
self._demod = blocks.complex_to_mag_squared()
if use_dcblock:
self._dcblock = filter.dc_blocker_cc(100*self._spc,True)
self.connect(self, self._dcblock, self._demod)
else:
self.connect(self, self._demod)
self._dcblock = None
self._bb = self._demod
# Pulse matched filter for 0.5us pulses
if use_pmf:
self._pmf = blocks.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)
self._avg = blocks.moving_average_ff(48*self._spc, 1.0/(48*self._spc))#, self._rate) # 3 preambles
# Synchronize to Mode-S preamble
self._sync = air_modes_swig.preamble(self._rate, self._threshold)
# Slice Mode-S bits and send to message queue
self._slicer = air_modes_swig.slicer(self._queue)
# Wire up the flowgraph
self.connect(self._bb, (self._sync, 0))
self.connect(self._bb, self._avg, (self._sync, 1))
self.connect(self._sync, self._slicer)
def set_rate(self, rate):
self._sync.set_rate(rate)
self._spc = int(rate/2e6)
self._avg.set_length_and_scale(48*self._spc, 1.0/(48*self._spc))
if self._bb != self._demod:
self._pmf.set_length_and_scale(self._spc, 1.0/self._spc)
if self._dcblock is not None:
self._dcblock.set_length(100*self._spc)
def set_threshold(self, threshold):
self._sync.set_threshold(threshold)
def set_pmf(self, pmf):
#TODO must be done when top block is stopped
pass
def get_pmf(self, pmf):
return not (self._bb == self._demod)
def get_threshold(self, threshold):
return self._sync.get_threshold()
class uplink_rx_path(gr.hier_block2):
def __init__(self, rate, threshold, queue, use_pmf=False, use_dcblock=False):
gr.hier_block2.__init__(self, "modes_uplink_rx_path",
gr.io_signature(1, 1, gr.sizeof_gr_complex),
gr.io_signature(0,0,0))
self._rate = int(rate)
self._threshold = threshold
self._queue = queue
self._spc = int(rate/4e6)
#demodulate DPSK via delay
self._delay = gr.delay(gr.sizeof_gr_complex, self._spc)
self._mult = gr.multiply_cc()
self._conj = gr.conjugate_cc()
self._c2r = gr.complex_to_real()
#self._bb = self._demod
self.filesink = gr.file_sink(gr.sizeof_float, "wat.dat")
# Pulse matched filter for 0.25us 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)
self._avg = gr.moving_average_ff(48*self._spc, 1.0/(48*self._spc), self._rate) # 3 preambles
# Synchronize to uplink preamble
self._sync = air_modes_swig.modes_uplink(self._rate, self._threshold)
# Slice Mode-S bits and send to message queue
# self._slicer = air_modes_swig.modes_slicer(self._rate, self._queue)
# Wire up the flowgraph
self.connect(self, (self._mult, 0))
self.connect(self, self._delay, self._conj, (self._mult, 1))
self.connect(self._mult, self._c2r)
self.connect(self._c2r, (self._sync, 0))
self.connect(self._c2r, self._avg, (self._sync, 1))
# self.connect(self._sync, self._slicer)
self.connect(self._sync, self.filesink)