gr-digitalhf/examples/s4285.py

72 lines
2.6 KiB
Python

## -*- python -*-
import numpy as np
from gnuradio import digital
class PhysicalLayer(object):
"""Physical layer description for STANAG 4285"""
def __init__(self, mode=0):
"""For STANAG 4258 the mode has to be set manually: mode=0 -> BPSK, mode=1 -> QPSK, mode=2 -> 8PSK"""
print('Hello from PhysicalLayer!\n')
self._preamble = [get_preamble(), digital.constellation_bpsk()]
self._constellations = [digital.constellation_bpsk(),
digital.constellation_qpsk(),
digital.constellation_8psk()]
self._data = [get_data(), self._constellations[mode]]
self._counter = 0
def __del__(self):
print('Bye from PhysicalLayer!\n')
def set_mode(self):
"""For STANAG 4258 the mode has to be set manually: mode=0 -> BPSK, mode=1 -> QPSK, mode=2 -> 8PSK"""
self._data[1] = self._constellations[mode];
def get_frame(self):
"""returns the known+unknown symbols and scrambling"""
print('get_frame', self._counter, self._preamble, self._preamble[1].__deref__())
if self._counter == 0:
return self._preamble
else:
return self._data
def get_doppler(self, symbols):
"""used for doppler shift update, for determining which frame to provide next,
and for stopping at end of data/when the signal quality is too low"""
self._counter = (self._counter+1)&2
## TODO: doppler calculations
doppler = 0.0
return [True, doppler]
def get_preamble():
"""preamble symbols + scrambler(=1)"""
state = np.array([1,1,0,1,0], dtype='b')
taps = np.array([0,0,1,0,1], dtype='b')
p = np.zeros(80, dtype='f')
for i in range(80):
p[i] = state[-1];
state = np.concatenate(([np.sum(state&taps)&1], state[0:-1]))
a = np.zeros(80, dtype=[('symb','c'), ('scramble', 'c')])
## BPSK modulation
a['symb'] = np.exp(np.pi*1j*p)
a['scramble'] = 1;
return a
def get_data():
"""data symbols + scrambler; for unknown symbols 'symb'=0"""
state = np.array([1,1,1,1,1,1,1,1,1], dtype='b')
taps = np.array([0,0,0,0,1,0,0,0,1], dtype='b')
p = np.zeros(176, dtype='f')
for i in range(176):
p[i] = np.sum(state[-3:]*[4,2,1]);
for j in range(3):
state = np.concatenate(([np.sum(state&taps)&1], state[0:-1]))
a=np.zeros(176, dtype=[('symb','c'), ('scramble', 'c')])
## PSK-8 modulation
a['scramble'] = np.exp(np.pi*1j*p/4)
a['symb'][ 32: 48] = 1; ## mini-probe 1
a['symb'][ 80: 96] = 1; ## mini-probe 2
a['symb'][128:144] = 1; ## mini-probe 3
return a