mirror of
https://github.com/hb9fxq/gr-digitalhf
synced 2024-12-22 07:09:59 +00:00
make the current doppler offset estimate available
This commit is contained in:
parent
95cb14d38e
commit
b846571748
|
@ -34,6 +34,7 @@ class msg_proxy(gr.basic_block):
|
|||
out_sig=[])
|
||||
self._obj = physical_layer_object
|
||||
self._quality = 0.0
|
||||
self._doppler = 0.0
|
||||
|
||||
self._port_doppler = pmt.intern("doppler")
|
||||
self.message_port_register_in(self._port_doppler)
|
||||
|
@ -54,8 +55,9 @@ class msg_proxy(gr.basic_block):
|
|||
def msg_handler_doppler(self, msg_in):
|
||||
## print('-------------------- msg_handler_doppler --------------------')
|
||||
iq_samples = pmt.to_python(pmt.cdr(msg_in))
|
||||
msg_out = pmt.to_pmt(self._obj.get_doppler(iq_samples))
|
||||
self.message_port_pub(self._port_doppler, msg_out)
|
||||
doppler = self._obj.get_doppler(iq_samples)
|
||||
self._doppler = doppler['doppler']
|
||||
self.message_port_pub(self._port_doppler, pmt.to_pmt(doppler))
|
||||
|
||||
def msg_handler_frame(self, msg_in):
|
||||
## print('-------------------- msg_handler_frame --------------------')
|
||||
|
@ -82,3 +84,6 @@ class msg_proxy(gr.basic_block):
|
|||
|
||||
def get_quality(self):
|
||||
return ('%5.1f %%' % self._quality)
|
||||
|
||||
def get_doppler(self):
|
||||
return self._doppler
|
||||
|
|
|
@ -105,6 +105,7 @@ class PhysicalLayer(object):
|
|||
self._viterbi_dec = viterbi27(0x6d, 0x4f)
|
||||
self._repeat = 1
|
||||
self._mode_descr = 'UNKNOWN'
|
||||
self._fault_counter = 0
|
||||
|
||||
def get_constellations(self):
|
||||
return self._constellations
|
||||
|
@ -121,6 +122,7 @@ class PhysicalLayer(object):
|
|||
success = True
|
||||
if len(symbols) == 0:
|
||||
self._frame_counter = -1
|
||||
self._fault_counter = 0
|
||||
s = self.get_preamble()
|
||||
s.resize(15+len(s))
|
||||
s['scramble'][-15:] = 1
|
||||
|
@ -177,12 +179,20 @@ class PhysicalLayer(object):
|
|||
tests = [np.abs(mean_s) > 0.4,
|
||||
np.real(mean_s) > np.imag(mean_s)]
|
||||
print('FRAME_QUALITY: ', s, mean_s, tests)
|
||||
success = all(tests)
|
||||
if all(tests):
|
||||
self._fault_counter -= 1
|
||||
else:
|
||||
self._fault_counter += 1
|
||||
self._fault_counter = min(11, max(0, self._fault_counter))
|
||||
success = self._fault_counter < 10
|
||||
if not success:
|
||||
self._fault_counter = 0
|
||||
return success
|
||||
|
||||
def get_doppler(self, iq_samples):
|
||||
"""quality check and doppler estimation for preamble"""
|
||||
r = {'success': False, ## -- quality flag
|
||||
'use_amp_est': self._frame_counter < 0,
|
||||
'doppler': 0} ## -- doppler estimate (rad/symb)
|
||||
if len(iq_samples) != 0:
|
||||
sps = self._sps
|
||||
|
@ -215,10 +225,11 @@ class PhysicalLayer(object):
|
|||
tt[0] = np.abs(np.vdot(t, self._preamble['symb'][0:15]))
|
||||
for i in range(1,len(tt)):
|
||||
tt[i] = np.abs(np.vdot(t, np.roll(M1, -SHIFTS[i-1])[0:15]))
|
||||
print('XXX ', tt)
|
||||
ii = np.argmax(tt)
|
||||
## TODO: add a meaningful QA test
|
||||
return True,ii
|
||||
imax = np.argmax(tt)
|
||||
test = tt[imax] / (np.sum(tt) - tt[imax]) * len(MODES)
|
||||
success = test > 3
|
||||
print('XXX ', test, tt)
|
||||
return success,imax
|
||||
|
||||
def set_mode(self, _):
|
||||
pass
|
||||
|
|
|
@ -309,6 +309,7 @@ class PhysicalLayer(object):
|
|||
def get_doppler(self, iq_samples):
|
||||
"""quality check and doppler estimation for preamble"""
|
||||
r = {'success': False, ## -- quality flag
|
||||
'use_amp_est': self._frame_counter < 0,
|
||||
'doppler': 0} ## -- doppler estimate (rad/symb)
|
||||
if len(iq_samples) != 0:
|
||||
sps = self._sps
|
||||
|
|
|
@ -52,6 +52,8 @@ class PhysicalLayer(object):
|
|||
self._data = self.get_data()
|
||||
self._viterbi_decoder = viterbi27(0x6d, 0x4f)
|
||||
self._mode_description = None
|
||||
self._frame_counter = -1
|
||||
self._fault_counter = 0
|
||||
|
||||
def set_mode(self, mode):
|
||||
"""set modulation and interleaver: 'BPS/S' or 'BPS/L'"""
|
||||
|
@ -61,6 +63,7 @@ class PhysicalLayer(object):
|
|||
self._deinterleaver = Deinterleaver(DEINTERLEAVER_INCR[intl] * MODES[bps]['deintl_multiple'])
|
||||
self._depuncturer = common.Depuncturer(repeat = MODES[bps]['repeat'],
|
||||
puncture_pattern = MODES[bps]['punct'])
|
||||
self._fault_counter = 0
|
||||
|
||||
def get_mode(self):
|
||||
return self._mode_description
|
||||
|
@ -82,8 +85,18 @@ class PhysicalLayer(object):
|
|||
frame_description = [self._preamble,MODE_BPSK,success,False]
|
||||
else: ## current frame is a preamble frame
|
||||
idx = range(30,80)
|
||||
idx = range(50)
|
||||
z = symbols[idx]*np.conj(self._preamble['symb'][idx])
|
||||
success = bool(np.sum(np.real(z)<0) < 30)
|
||||
mean_z = np.mean(z)
|
||||
if np.sum(np.real(z)<0) < 30 and np.real(mean_z) > np.abs(np.imag(mean_z)) and np.real(mean_z) > 0.3:
|
||||
self._fault_counter -= 1
|
||||
else:
|
||||
self._fault_counter += 1
|
||||
self._fault_counter = min(11, max(0, self._fault_counter))
|
||||
success = self._fault_counter < 10
|
||||
if not success:
|
||||
self._frame_counter = -2
|
||||
self._fault_counter = 0
|
||||
frame_description = [self._data,self._mode,success,True]
|
||||
|
||||
self._frame_counter += 1
|
||||
|
@ -91,6 +104,7 @@ class PhysicalLayer(object):
|
|||
|
||||
def get_doppler(self, iq_samples):
|
||||
r = {'success': False, ## -- quality flag
|
||||
'use_amp_est': self._frame_counter < 0,
|
||||
'doppler': 0} ## -- doppler estimate (rad/symb)
|
||||
if len(iq_samples) == 0:
|
||||
return r
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#
|
||||
|
||||
import importlib
|
||||
import math
|
||||
from gnuradio import blocks
|
||||
from gnuradio import digital
|
||||
from gnuradio import filter
|
||||
|
@ -46,6 +47,7 @@ class physical_layer_driver(gr.hier_block2):
|
|||
self._nB = nB
|
||||
self._nF = nF
|
||||
self._nW = nW
|
||||
self._samp_rate = samp_rate
|
||||
|
||||
m = importlib.import_module('digitalhf.physical_layer.'+description_name)
|
||||
self._physical_layer_driver_description = m.PhysicalLayer(sps)
|
||||
|
@ -60,8 +62,8 @@ class physical_layer_driver(gr.hier_block2):
|
|||
self._corr_est = digital.corr_est_cc(symbols = (preamble_samples.tolist()),
|
||||
sps = sps,
|
||||
mark_delay = preamble_offset,
|
||||
threshold = 0.1,
|
||||
threshold_method = 1)
|
||||
threshold = 1-math.exp(-5),
|
||||
threshold_method = 0)
|
||||
self._doppler_correction = digitalhf.doppler_correction_cc(preamble_length, len(preamble_samples))
|
||||
self._adaptive_filter = digitalhf.adaptive_dfe(sps, nB, nF, nW, mu, alpha)
|
||||
self._msg_proxy = digitalhf.msg_proxy(self._physical_layer_driver_description)
|
||||
|
@ -109,3 +111,6 @@ class physical_layer_driver(gr.hier_block2):
|
|||
|
||||
def get_mode(self):
|
||||
return self._physical_layer_driver_description.get_mode()
|
||||
|
||||
def get_doppler(self):
|
||||
return '%+4.1f Hz' % (self._msg_proxy.get_doppler()*self._samp_rate/(2*math.pi))
|
||||
|
|
Loading…
Reference in a new issue