added deinterleaving (intermediate)

This commit is contained in:
cmayer 2019-05-10 11:48:56 +02:00
parent 4e5d41573d
commit 976526913d
9 changed files with 338 additions and 448 deletions

View File

@ -437,7 +437,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(426, 368)</value>
<value>(426, 442)</value>
</param>
<param>
<key>_rotation</key>
@ -460,6 +460,57 @@
<value>1</value>
</param>
</block>
<block>
<key>blocks_file_sink</key>
<param>
<key>append</key>
<value>False</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>file</key>
<value>/Users/chm/Software/gr-digitalhf/examples/test_bits.bin</value>
</param>
<param>
<key>_coordinate</key>
<value>(149, 293)</value>
</param>
<param>
<key>_rotation</key>
<value>180</value>
</param>
<param>
<key>id</key>
<value>blocks_file_sink_0</value>
</param>
<param>
<key>type</key>
<value>byte</value>
</param>
<param>
<key>unbuffered</key>
<value>True</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>blocks_float_to_complex</key>
<param>
@ -527,7 +578,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(714, 261)</value>
<value>(704, 261)</value>
</param>
<param>
<key>_rotation</key>
@ -550,6 +601,53 @@
<value>(1+(nB+nF)*sps)</value>
</param>
</block>
<block>
<key>blocks_pdu_to_tagged_stream</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>_coordinate</key>
<value>(405, 304)</value>
</param>
<param>
<key>_rotation</key>
<value>180</value>
</param>
<param>
<key>id</key>
<value>blocks_pdu_to_tagged_stream_0</value>
</param>
<param>
<key>type</key>
<value>byte</value>
</param>
<param>
<key>tag</key>
<value>packet_len</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
</block>
<block>
<key>blocks_tag_debug</key>
<param>
@ -708,7 +806,7 @@
</param>
<param>
<key>repeat</key>
<value>True</value>
<value>False</value>
</param>
</block>
<block>
@ -735,7 +833,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(661, 325)</value>
<value>(704, 346)</value>
</param>
<param>
<key>_rotation</key>
@ -814,7 +912,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(394, 464)</value>
<value>(352, 528)</value>
</param>
<param>
<key>gui_hint</key>
@ -1169,7 +1267,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(181, 357)</value>
<value>(181, 432)</value>
</param>
<param>
<key>gui_hint</key>
@ -1536,7 +1634,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(426, 293)</value>
<value>(448, 368)</value>
</param>
<param>
<key>gui_hint</key>
@ -1840,7 +1938,7 @@
</param>
<param>
<key>tr_tag</key>
<value>"soft_dec"</value>
<value>"packet_len"</value>
</param>
<param>
<key>type</key>
@ -2108,6 +2206,12 @@
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_pdu_to_tagged_stream_0</source_block_id>
<sink_block_id>blocks_file_sink_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_throttle_0</source_block_id>
<sink_block_id>digitalhf_physical_layer_driver_0</sink_block_id>
@ -2132,6 +2236,12 @@
<source_key>1</source_key>
<sink_key>1</sink_key>
</connection>
<connection>
<source_block_id>digitalhf_physical_layer_driver_0</source_block_id>
<sink_block_id>blocks_pdu_to_tagged_stream_0</sink_block_id>
<source_key>bits</source_key>
<sink_key>pdus</sink_key>
</connection>
<connection>
<source_block_id>digitalhf_physical_layer_driver_0</source_block_id>
<sink_block_id>blocks_complex_to_mag_0</sink_block_id>

View File

@ -93,77 +93,6 @@
<value>(0,0)</value>
</param>
</block>
<block>
<key>variable_cc_decoder_def</key>
<param>
<key>padding</key>
<value>False</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>k</key>
<value>7</value>
</param>
<param>
<key>dim1</key>
<value>1</value>
</param>
<param>
<key>dim2</key>
<value>1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>state_end</key>
<value>-1</value>
</param>
<param>
<key>framebits</key>
<value>30*8</value>
</param>
<param>
<key>_coordinate</key>
<value>(32, 341)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>CCSDS_27</value>
</param>
<param>
<key>value</key>
<value>"ok"</value>
</param>
<param>
<key>ndim</key>
<value>0</value>
</param>
<param>
<key>polys</key>
<value>[109,79]</value>
</param>
<param>
<key>rate</key>
<value>2</value>
</param>
<param>
<key>state_start</key>
<value>0</value>
</param>
<param>
<key>mode</key>
<value>fec.CC_STREAMING</value>
</param>
</block>
<block>
<key>variable_qtgui_range</key>
<param>
@ -235,7 +164,7 @@
</param>
<param>
<key>value</key>
<value>0</value>
<value>'600/L'</value>
</param>
<param>
<key>_enabled</key>
@ -287,7 +216,7 @@
</param>
<param>
<key>num_opts</key>
<value>3</value>
<value>0</value>
</param>
<param>
<key>option0</key>
@ -311,7 +240,7 @@
</param>
<param>
<key>options</key>
<value>[0, 1, 2]</value>
<value>['2400/L', '1200/L', '600/L', '300/L', '150/L', '75/L']</value>
</param>
<param>
<key>orient</key>
@ -524,49 +453,6 @@
<value>5</value>
</param>
</block>
<block>
<key>variable_dummy_decoder_def</key>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>dim1</key>
<value>1</value>
</param>
<param>
<key>dim2</key>
<value>1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>framebits</key>
<value>2048</value>
</param>
<param>
<key>_coordinate</key>
<value>(106, 634)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>variable_dummy_decoder_def_0</value>
</param>
<param>
<key>value</key>
<value>"ok"</value>
</param>
<param>
<key>ndim</key>
<value>0</value>
</param>
</block>
<block>
<key>analog_agc2_xx</key>
<param>
@ -650,7 +536,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(533, 368)</value>
<value>(490, 464)</value>
</param>
<param>
<key>_rotation</key>
@ -701,11 +587,11 @@
</param>
<param>
<key>_coordinate</key>
<value>(1109, 581)</value>
<value>(192, 304)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
<value>180</value>
</param>
<param>
<key>id</key>
@ -724,57 +610,6 @@
<value>1</value>
</param>
</block>
<block>
<key>blocks_file_sink</key>
<param>
<key>append</key>
<value>False</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>file</key>
<value>/Users/chm/Software/gr-digitalhf/examples/soft_dec_test.bin</value>
</param>
<param>
<key>_coordinate</key>
<value>(864, 506)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_file_sink_0_0</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>unbuffered</key>
<value>False</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>blocks_float_to_complex</key>
<param>
@ -842,11 +677,11 @@
</param>
<param>
<key>_coordinate</key>
<value>(586, 314)</value>
<value>(778, 250)</value>
</param>
<param>
<key>_rotation</key>
<value>180</value>
<value>0</value>
</param>
<param>
<key>id</key>
@ -881,15 +716,15 @@
</param>
<param>
<key>_enabled</key>
<value>True</value>
<value>1</value>
</param>
<param>
<key>_coordinate</key>
<value>(576, 592)</value>
<value>(448, 314)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
<value>180</value>
</param>
<param>
<key>id</key>
@ -897,7 +732,7 @@
</param>
<param>
<key>type</key>
<value>float</value>
<value>byte</value>
</param>
<param>
<key>tag</key>
@ -967,53 +802,6 @@
<value>1</value>
</param>
</block>
<block>
<key>blocks_tagged_stream_to_pdu</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(490, 730)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_tagged_stream_to_pdu_0</value>
</param>
<param>
<key>type</key>
<value>byte</value>
</param>
<param>
<key>tag</key>
<value>packet_len</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
</block>
<block>
<key>blocks_throttle</key>
<param>
@ -1144,7 +932,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(736, 314)</value>
<value>(768, 325)</value>
</param>
<param>
<key>_rotation</key>
@ -1195,104 +983,6 @@
<value>samp_rate</value>
</param>
</block>
<block>
<key>fec_decode_ccsds_27_fb</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(853, 805)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>fec_decode_ccsds_27_fb_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
</block>
<block>
<key>fec_extended_decoder</key>
<param>
<key>ann</key>
<value>None</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>decoder_list</key>
<value>CCSDS_27</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(853, 618)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>fec_extended_decoder_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>puncpat</key>
<value>'11'</value>
</param>
<param>
<key>threadtype</key>
<value>capillary</value>
</param>
<param>
<key>value</key>
<value>fec_extended_decoder</value>
</param>
</block>
<block>
<key>qtgui_const_sink_x</key>
<param>
@ -1321,7 +1011,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(320, 442)</value>
<value>(437, 549)</value>
</param>
<param>
<key>gui_hint</key>
@ -1676,7 +1366,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(320, 357)</value>
<value>(245, 453)</value>
</param>
<param>
<key>gui_hint</key>
@ -2043,7 +1733,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(320, 272)</value>
<value>(490, 389)</value>
</param>
<param>
<key>gui_hint</key>
@ -2351,7 +2041,7 @@
</param>
<param>
<key>type</key>
<value>float</value>
<value>msg_float</value>
</param>
<param>
<key>update_time</key>
@ -2617,25 +2307,7 @@
</connection>
<connection>
<source_block_id>blocks_pdu_to_tagged_stream_0</source_block_id>
<sink_block_id>blocks_file_sink_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_pdu_to_tagged_stream_0</source_block_id>
<sink_block_id>fec_decode_ccsds_27_fb_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_pdu_to_tagged_stream_0</source_block_id>
<sink_block_id>fec_extended_decoder_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_pdu_to_tagged_stream_0</source_block_id>
<sink_block_id>qtgui_time_sink_x_1</sink_block_id>
<sink_block_id>blocks_file_sink_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
@ -2663,6 +2335,12 @@
<source_key>1</source_key>
<sink_key>1</sink_key>
</connection>
<connection>
<source_block_id>digitalhf_physical_layer_driver_0</source_block_id>
<sink_block_id>blocks_pdu_to_tagged_stream_0</sink_block_id>
<source_key>bits</source_key>
<sink_key>pdus</sink_key>
</connection>
<connection>
<source_block_id>digitalhf_physical_layer_driver_0</source_block_id>
<sink_block_id>blocks_complex_to_mag_0</sink_block_id>
@ -2677,9 +2355,9 @@
</connection>
<connection>
<source_block_id>digitalhf_physical_layer_driver_0</source_block_id>
<sink_block_id>blocks_pdu_to_tagged_stream_0</sink_block_id>
<sink_block_id>qtgui_time_sink_x_1</sink_block_id>
<source_key>soft_dec</source_key>
<sink_key>pdus</sink_key>
<sink_key>in</sink_key>
</connection>
<connection>
<source_block_id>digitalhf_physical_layer_driver_0</source_block_id>
@ -2687,28 +2365,4 @@
<source_key>2</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>fec_decode_ccsds_27_fb_0</source_block_id>
<sink_block_id>blocks_file_sink_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>fec_decode_ccsds_27_fb_0</source_block_id>
<sink_block_id>blocks_tag_debug_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>fec_extended_decoder_0</source_block_id>
<sink_block_id>blocks_file_sink_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>fec_extended_decoder_0</source_block_id>
<sink_block_id>blocks_tag_debug_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
</flow_graph>

View File

@ -74,6 +74,12 @@
<optional>1</optional>
</source>
<source>
<name>bits</name>
<type>message</type>
<optional>1</optional>
</source>
<source>
<name>taps</name>
<type>complex</type>

View File

@ -44,8 +44,8 @@ class msg_proxy(gr.basic_block):
self.message_port_register_out(self._port_frame_info)
self.set_msg_handler(self._port_frame_info, self.msg_handler_frame)
self._port_soft_dec = pmt.intern("soft_dec")
self.message_port_register_out(self._port_soft_dec)
self._port_bits = pmt.intern("bits")
self.message_port_register_out(self._port_bits)
def msg_handler_doppler(self, msg_in):
## print('-------------------- msg_handler_doppler --------------------')
@ -60,19 +60,16 @@ class msg_proxy(gr.basic_block):
def msg_handler_frame(self, msg_in):
## print('-------------------- msg_handler_frame --------------------')
## print(msg_in)
symbols = pmt.to_python(pmt.dict_ref(msg_in, pmt.intern('symbols'), pmt.PMT_NIL))
symbols = pmt.to_python(pmt.dict_ref(msg_in, pmt.intern('symbols'), pmt.PMT_NIL))
soft_dec = pmt.to_python(pmt.dict_ref(msg_in, pmt.intern('soft_dec'), pmt.PMT_NIL))
symb,constellation_idx,do_continue,save_soft_dec = self._obj.get_next_frame(symbols)
if do_continue and len(soft_dec) != 0:
d = self._obj.decode_soft_dec(soft_dec)
bits = np.array(self._obj.decode_soft_dec(soft_dec), dtype=np.uint8)
msg_out = pmt.make_dict()
msg_out = pmt.dict_add(msg_out, pmt.intern('packet_len'), pmt.to_pmt(len(d)))
d = np.array(d, dtype=np.float32)
d[abs(d)==np.Inf] = 0
vv = pmt.to_pmt(d)
msg = pmt.cons(msg_out, vv)
self.message_port_pub(self._port_soft_dec, msg)
## TODO: publish the bits if success
msg_out = pmt.dict_add(msg_out, pmt.intern('packet_len'), pmt.to_pmt(len(bits)))
msg = pmt.cons(msg_out, pmt.to_pmt(bits))
self.message_port_pub(self._port_bits, msg)
##print('symb=', symb, symb['symb'], symb['scramble'])
msg_out = pmt.make_dict()
msg_out = pmt.dict_add(msg_out, pmt.intern('symb'), pmt.to_pmt(symb['symb']))

View File

@ -3,6 +3,7 @@
from __future__ import print_function
import numpy as np
import common
from digitalhf.digitalhf_swig import viterbi27
## ---- Walsh-4 codes -----------------------------------------------------------
WALSH = np.array([[0,0,0,0, 0,0,0,0], # 0 - 000
@ -75,26 +76,26 @@ MODE_8PSK=2
## ---- mode definitions --------------------------------------------------------
MODE = [[{} for _ in range(8)] for _ in range(8)]
MODE[7][6] = {'bit_rate':4800, 'ci':MODE_8PSK, 'interleaver':['N', 1, 1], 'unknown':32,'known':16, 'nsymb': 1, 'coding_rate': -1 }
MODE[7][7] = {'bit_rate':2400, 'ci':MODE_8PSK, 'interleaver':['N', 1, 1], 'unknown':32,'known':16, 'nsymb': 1, 'coding_rate':1./2}
MODE[7][6] = {'bit_rate':4800, 'ci':MODE_8PSK, 'interleaver':['N', 1, 1], 'unknown':32,'known':16, 'nsymb': 1, 'coding_rate': 'n/a', 'repeat': 1}
MODE[7][7] = {'bit_rate':2400, 'ci':MODE_8PSK, 'interleaver':['N', 1, 1], 'unknown':32,'known':16, 'nsymb': 1, 'coding_rate': '1/2', 'repeat': 1}
MODE[6][4] = {'bit_rate':2400, 'ci':MODE_8PSK, 'interleaver':['S', 40, 72], 'unknown':32,'known':16, 'nsymb': 1, 'coding_rate':1./2}
MODE[4][4] = {'bit_rate':2400, 'ci':MODE_8PSK, 'interleaver':['L', 40,576], 'unknown':32,'known':16, 'nsymb': 1, 'coding_rate':1./2}
MODE[6][4] = {'bit_rate':2400, 'ci':MODE_8PSK, 'interleaver':['S', 40, 72], 'unknown':32,'known':16, 'nsymb': 1, 'coding_rate': '1/2', 'repeat': 1}
MODE[4][4] = {'bit_rate':2400, 'ci':MODE_8PSK, 'interleaver':['L', 40,576], 'unknown':32,'known':16, 'nsymb': 1, 'coding_rate': '1/2', 'repeat': 1}
MODE[6][5] = {'bit_rate':1200, 'ci':MODE_QPSK, 'interleaver':['S', 40, 36], 'unknown':20,'known':20, 'nsymb': 1, 'coding_rate':1./2}
MODE[4][5] = {'bit_rate':1200, 'ci':MODE_QPSK, 'interleaver':['L', 40,288], 'unknown':20,'known':20, 'nsymb': 1, 'coding_rate':1./2}
MODE[6][5] = {'bit_rate':1200, 'ci':MODE_QPSK, 'interleaver':['S', 40, 36], 'unknown':20,'known':20, 'nsymb': 1, 'coding_rate': '1/2', 'repeat': 1}
MODE[4][5] = {'bit_rate':1200, 'ci':MODE_QPSK, 'interleaver':['L', 40,288], 'unknown':20,'known':20, 'nsymb': 1, 'coding_rate': '1/2', 'repeat': 1}
MODE[6][6] = {'bit_rate': 600, 'ci':MODE_BPSK, 'interleaver':['S', 40, 18], 'unknown':20,'known':20, 'nsymb': 1, 'coding_rate':1./2}
MODE[4][6] = {'bit_rate': 600, 'ci':MODE_BPSK, 'interleaver':['L', 40,144], 'unknown':20,'known':20, 'nsymb': 1, 'coding_rate':1./2}
MODE[6][6] = {'bit_rate': 600, 'ci':MODE_BPSK, 'interleaver':['S', 40, 18], 'unknown':20,'known':20, 'nsymb': 1, 'coding_rate': '1/2', 'repeat': 1}
MODE[4][6] = {'bit_rate': 600, 'ci':MODE_BPSK, 'interleaver':['L', 40,144], 'unknown':20,'known':20, 'nsymb': 1, 'coding_rate': '1/2', 'repeat': 1}
MODE[6][7] = {'bit_rate': 300, 'ci':MODE_BPSK, 'interleaver':['S', 40, 18], 'unknown':20,'known':20, 'nsymb': 1, 'coding_rate':1./4}
MODE[4][7] = {'bit_rate': 300, 'ci':MODE_BPSK, 'interleaver':['L', 40,144], 'unknown':20,'known':20, 'nsymb': 1, 'coding_rate':1./4}
MODE[6][7] = {'bit_rate': 300, 'ci':MODE_BPSK, 'interleaver':['S', 40, 18], 'unknown':20,'known':20, 'nsymb': 1, 'coding_rate': '1/4', 'repeat': 2}
MODE[4][7] = {'bit_rate': 300, 'ci':MODE_BPSK, 'interleaver':['L', 40,144], 'unknown':20,'known':20, 'nsymb': 1, 'coding_rate': '1/4', 'repeat': 2}
MODE[7][4] = {'bit_rate': 150, 'ci':MODE_BPSK, 'interleaver':['S', 40, 18], 'unknown':20,'known':20, 'nsymb': 1, 'coding_rate':1./8}
MODE[5][4] = {'bit_rate': 150, 'ci':MODE_BPSK, 'interleaver':['L', 40,144], 'unknown':20,'known':20, 'nsymb': 1, 'coding_rate':1./8}
MODE[7][4] = {'bit_rate': 150, 'ci':MODE_BPSK, 'interleaver':['S', 40, 18], 'unknown':20,'known':20, 'nsymb': 1, 'coding_rate': '1/8', 'repeat': 4}
MODE[5][4] = {'bit_rate': 150, 'ci':MODE_BPSK, 'interleaver':['L', 40,144], 'unknown':20,'known':20, 'nsymb': 1, 'coding_rate': '1/8', 'repeat': 4}
MODE[7][5] = {'bit_rate': 75, 'ci':MODE_QPSK, 'interleaver':['S', 10, 9], 'unknown':-1,'known': 0, 'nsymb':32, 'coding_rate':1./2}
MODE[5][4] = {'bit_rate': 75, 'ci':MODE_QPSK, 'interleaver':['L', 20, 36], 'unknown':-1,'known': 0, 'nsymb':32, 'coding_rate':1./2}
MODE[7][5] = {'bit_rate': 75, 'ci':MODE_QPSK, 'interleaver':['S', 10, 9], 'unknown':-1,'known': 0, 'nsymb':32, 'coding_rate': '1/2', 'repeat': 1}
MODE[5][4] = {'bit_rate': 75, 'ci':MODE_QPSK, 'interleaver':['L', 20, 36], 'unknown':-1,'known': 0, 'nsymb':32, 'coding_rate': '1/2', 'repeat': 1}
## ---- deinterleaver -----------------------------------------------------------
@ -172,7 +173,7 @@ class PhysicalLayer(object):
return [self.get_next_data_frame(success),self._mode['ci'],success,success]
else: ## data mode
self._frame_counter += 1
print('test:', symbols[self._mode['unknown']:], np.mean(np.real(symbols[self._mode['unknown']:])))
##print('test:', symbols[self._mode['unknown']:], np.mean(np.real(symbols[self._mode['unknown']:])))
if self._frame_counter < self._num_frames_per_block-2:
success = np.mean(np.real(symbols[self._mode['unknown']:])) > 0.7
return [self.get_next_data_frame(success),self._mode['ci'],success,success]
@ -205,8 +206,9 @@ class PhysicalLayer(object):
for _ in range(sps)], dtype=np.complex64)
## find starting point
_,_zp = self.get_preamble_z()
cc = np.correlate(iq_samples, _zp) ##zp[0:3*32*sps])
cc = np.correlate(iq_samples, zp[0:3*32*sps])
imax = np.argmax(np.abs(cc[0:2*32*sps]))
print('imax=', imax, len(iq_samples), len(cc))
apks = np.abs(cc[(imax, imax+3*32*sps),])
tpks = np.abs(cc[imax+3*16*sps:imax+5*16*sps])
print('imax=', imax, 'apks=',apks,
@ -232,12 +234,14 @@ class PhysicalLayer(object):
print('data=',data)
self._pre_counter = sum([(x&3)*(1<<2*y) for (x,y) in zip(data[11:14][::-1], range(3))])
self._d1d2 = data[9:11]
self._mode = MODE[data[9]][data[10]]
self._block_len = 11520 if self._mode['interleaver'][0] == 'L' else 1440
self._frame_len = self._mode['known'] + self._mode['unknown']
self._mode = mode = MODE[data[9]][data[10]]
self._block_len = 11520 if mode['interleaver'][0] == 'L' else 1440
self._frame_len = mode['known'] + mode['unknown']
self._num_frames_per_block = self._block_len/self._frame_len;
self._deinterleaver = Deinterleaver(self._mode['interleaver'][1], self._mode['interleaver'][2])
print(self._d1d2, self._mode, self._frame_len)
self._deinterleaver = Deinterleaver(mode['interleaver'][1], mode['interleaver'][2])
self._depuncturer = common.Depuncturer(repeat=mode['repeat'])
self._viterbi_decoder = viterbi27(0x6d, 0x4f)
print(self._d1d2, mode, self._frame_len)
return True
def set_mode(self, _):
@ -247,10 +251,17 @@ class PhysicalLayer(object):
print('decode_soft_dec', len(soft_dec), soft_dec.dtype)
r = self._deinterleaver.load(soft_dec)
print('decode_soft_dec r=', r.shape)
if r.shape[0] != 0:
for i in range(r.shape[0]//4):
print('BB:', r[4*i]<0, r[4*i+2]<0, '|', r[4*i+1]<0, r[4*i+3]<0)
return soft_dec ## TODO
if r.shape[0] == 0:
return []
##for i in range(r.shape[0]//4):
## print('BB:', r[4*i]<0, r[4*i+2]<0, '|', r[4*i+1]<0, r[4*i+3]<0)
rd = self._depuncturer.process(r)
self._viterbi_decoder.reset()
decoded_bits = self._viterbi_decoder.udpate(rd)
print('bits=', decoded_bits)
print('quality={}%'.format(100.0*self._viterbi_decoder.quality()/(2*len(decoded_bits))))
return decoded_bits
@staticmethod
def get_preamble():

View File

@ -3,11 +3,12 @@
from __future__ import print_function
import numpy as np
import common
from digitalhf.digitalhf_swig import viterbi27, viterbi29
## ---- constellations ---------------------------------------------------------
BPSK=np.array(zip(np.exp(2j*np.pi*np.arange(2)/2), [0,1]), common.CONST_DTYPE)
QPSK=np.array(zip(np.exp(2j*np.pi*np.arange(4)/4), [0,1,3,2]), common.CONST_DTYPE)
PSK8=np.array(zip(np.exp(2j*np.pi*np.arange(8)/8), [1,0,2,3,6,7,5,4]), common.CONST_DTYPE)
PSK8=np.array(zip(np.exp(2j*np.pi*np.arange(8)/8), [1,0,2,3,7,6,4,5]), common.CONST_DTYPE)
QAM16=np.array(
zip([+0.866025+0.500000j, +0.500000+0.866025j, +1.000000+0.000000j, +0.258819+0.258819j,
-0.500000+0.866025j, +0.000000+1.000000j, -0.866025+0.500000j, -0.258819+0.258819j,
@ -580,7 +581,7 @@ CODE_RATE_PUNCT = { # [code rate][K] -> punct pattern, [code rate]['Rep'] -> # r
'5/6' : { 'K=7': [ '11010', '10101'], 'K=9': [ '10110', '11001'], 'Rep': 1 },
'4/5' : { 'K=7': [ '1111', '1000'], 'K=9': [ '1101', '1010'], 'Rep': 1 },
'3/4' : { 'K=7': [ '110', '101'], 'K=9': [ '111', '100'], 'Rep': 1 },
'2/3' : { 'K=7': [ '11', '10'], 'K=9': [ '11', '10'], 'Rep': 1 },
'2/3' : { 'K=7': [ '11', '10'], 'K=9': [ '11', '10'], 'Rep': 1 },
'4/7' : { 'K=7': [ '1111', '0111'], 'K=9': [ '1111', '0111'], 'Rep': 1 },
'9/16': { 'K=7': ['111101111','111111011'], 'K=9': ['111101111','111111011'], 'Rep': 1 },
'1/2' : { 'K=7': [ '1', '1'], 'K=9': [ '1', '1'], 'Rep': 1 },
@ -594,6 +595,28 @@ CODE_RATE_PUNCT = { # [code rate][K] -> punct pattern, [code rate]['Rep'] -> # r
'1/16': { 'K=7': [ '1', '1'], 'K=9': [ '1', '1'], 'Rep': 8 }
}
## ---- deinterleaver -----------------------------------------------------------
class Deinterleaver(object):
"""deinterleave"""
def __init__(self, length, incr):
self._length = length
self._array = np.zeros(length, dtype=np.float32)
self._incr = incr
self._idx = np.mod(incr*np.arange(length), length)
self._i = 0
def fetch(self):
self._i = 0
return self._array[self._idx]
def load(self, a):
print('deinterleaver load', len(a), self._i, self._incr, self._length)
input_len = len(a)
assert(self._i+input_len <= self._length)
self._array[self._i:self._i+input_len] = a
self._i += input_len
return (self._i == self._length)
## ---- Walsh-4 codes ----------------------------------------------------------
WALSH = np.array([[0,0,0,0], # 0 - 00
[0,1,0,1], # 1 - 01
@ -806,18 +829,26 @@ class PhysicalLayer(object):
b = np.flip(b)
self._wid = np.packbits(b[0:4])[0]>>4
self._intl_type = INTERLEAVERS[np.packbits(b[4:6])[0]>>6]
self._constraint_length = b[6]
self._constraint_length = 'K=7' if b[6] == 0 else 'K=9'
self._data_mode = WID_MODE[self._wid]
self._unknown = BW_UNKNOWN[self._bw][self._wid]
self._known = BW_KNOWN[self._bw][self._wid]
mp_info = MP_LEN_BASE_SHIFT[self._known]
self._mp = make_mp(self._known, mp_info['base_len'], 0)
self._mp_shifted = make_mp(self._known, mp_info['base_len'], mp_info['base_shift'])
self._intl_info = BW_INTL[self._bw][self._wid][self._intl_type]
self._intl_incr = BW_INTL_INCR[self._bw][self._wid][self._intl_type]
self._intl_frames = self._intl_info[0]
self._intl_bits = self._intl_info[1]
print('b=', b, success, self._wid, self._intl_type, self._intl_frames, self._intl_incr, self._constraint_length,
intl_info = BW_INTL[self._bw][self._wid][self._intl_type]
self._intl_frames = intl_info[0]
code_rate = BW_CODE_RATE[self._bw][self._wid]
punct = CODE_RATE_PUNCT[code_rate]
self._deinterleaver = Deinterleaver(length = intl_info[1],
incr = BW_INTL_INCR[self._bw][self._wid][self._intl_type])
self._depuncturer = common.Depuncturer(repeat = punct['Rep'],
puncture_pattern = punct[self._constraint_length])
self._viterbi_decoder = viterbi27(0x6d, 0x4f) if self._constraint_length == 'K=7' else viterbi29()
print('b=', b, success, self._wid, self._intl_type, self._intl_frames, self._constraint_length,
self._known, self._unknown)
return success
@ -851,9 +882,19 @@ class PhysicalLayer(object):
def decode_soft_dec(self, soft_dec):
print('decode_soft_dec', len(soft_dec), soft_dec.dtype)
return soft_dec ## TODO
is_full = self._deinterleaver.load(soft_dec)
if not is_full:
return []
def get_preamble():
r = self._deinterleaver.fetch()
rd = self._depuncturer.process(r)
self._viterbi_decoder.reset()
decoded_bits = self._viterbi_decoder.udpate(rd)
print('quality={}% num_bits={}'.format(100.0*self._viterbi_decoder.quality()/(2*len(decoded_bits)),
len(decoded_bits)))
return decoded_bits
def get_preamble(self):
"""fixed symbols + scrambler"""
return self._fixed_s
@ -865,9 +906,9 @@ class PhysicalLayer(object):
if __name__ == '__main__':
p = PhysicalLayer(5)
p.set_mode('24 kHz')
s = ScrambleData(3)
for i in range(10):
print(i, s.next())
print(np.real(make_mp(24,13,0)))
print(np.real(make_mp(24,13,6)))
#print(make_mp(72,36,0))
#s = ScrambleData(3)
#for i in range(10):
# print(i, s.next())
# print(np.real(make_mp(24,13,0)))
# print(np.real(make_mp(24,13,6)))
print(mp_base(196))

View File

@ -2,6 +2,9 @@
import numpy as np
import common
from digitalhf.digitalhf_swig import viterbi27
class Deinterleaver(object):
"S4285 deinterleaver"
def __init__(self, incr):
@ -18,17 +21,29 @@ class Deinterleaver(object):
def fetch(self):
return np.array([self._buf[(9*i)%32][0] for i in range(32)])
MODE_BPSK=0
MODE_QPSK=1
MODE_8PSK=2
MODES = { ## [BPS]['const'] [BPS]['punct'] [BPS]['repeat']
'2400': {'const': MODE_8PSK, 'punct': ['11', '10'] , 'repeat': 1},
'1200': {'const': MODE_QPSK, 'punct': [ '1', '1'] , 'repeat': 1},
'600': {'const': MODE_BPSK, 'punct': [ '1', '1'] , 'repeat': 1},
'300': {'const': MODE_BPSK, 'punct': [ '1', '1'] , 'repeat': 2},
'150': {'const': MODE_BPSK, 'punct': [ '1', '1'] , 'repeat': 4},
'75': {'const': MODE_BPSK, 'punct': [ '1', '1'] , 'repeat': 8}
}
DEINTERLEAVER_INCR = { 'S': 1, 'L': 12 }
class PhysicalLayer(object):
"""Physical layer description for STANAG 4285"""
MODE_BPSK=0
MODE_QPSK=1
MODE_8PSK=2
def __init__(self, sps):
"""intialization"""
self._sps = sps
self._mode = self.MODE_QPSK
##self._mode = self.MODE_QPSK
self._frame_counter = 0
self._is_first_frame = True
self._constellations = [self.make_psk(2, [0,1]),
@ -36,12 +51,16 @@ class PhysicalLayer(object):
self.make_psk(8, [1,0,2,3,6,7,5,4])]
self._preamble = self.get_preamble()
self._data = self.get_data()
self._deinterleaver = Deinterleaver(12) ## for now BPSK L fixed
self._viterbi_decoder = viterbi27(0x6d, 0x4f)
def set_mode(self, mode):
"""set phase modultation type"""
"""set phase modultation type: 'BPS/S' or 'BPS/L'"""
print('set_mode', mode)
self._mode = int(mode)
bps,intl = mode.split('/')
self._mode = MODES[bps]['const']
self._deinterleaver = Deinterleaver(DEINTERLEAVER_INCR[intl])
self._depuncturer = common.Depuncturer(repeat = MODES[bps]['repeat'],
puncture_pattern = MODES[bps]['punct'])
def get_constellations(self):
return self._constellations
@ -58,7 +77,7 @@ class PhysicalLayer(object):
success,frame_description = True,[]
if (self._frame_counter%2) == 0:
frame_description = [self._preamble,self.MODE_BPSK,success,False]
frame_description = [self._preamble,MODE_BPSK,success,False]
else:
idx = range(30,80)
z = symbols[idx]*np.conj(self._preamble['symb'][idx])
@ -106,13 +125,16 @@ class PhysicalLayer(object):
return 2,np.array([z for z in a['symb'][0:31] for _ in range(self._sps)])
def decode_soft_dec(self, soft_dec):
assert(len(soft_dec) == 128)
print('decode_soft_dec: ', len(soft_dec))
res = []
for i in range(0,128,32):
n = len(soft_dec)
r = []
for i in range(0,n,32):
self._deinterleaver.push(soft_dec[i:i+32])
res.extend(self._deinterleaver.fetch().tolist())
return res
r.extend(self._deinterleaver.fetch().tolist())
rd = self._depuncturer.process(np.array(r, dtype=np.float32))
decoded_bits = self._viterbi_decoder.udpate(rd)
print('bits=', decoded_bits)
print('quality={}%'.format(100.0*self._viterbi_decoder.quality()/(2*len(decoded_bits))))
return decoded_bits
@staticmethod
def get_preamble():

View File

@ -26,7 +26,53 @@ def freq_est(z):
mod_2pi = lambda x : np.mod(x-np.pi, 2*np.pi) - np.pi
return np.sum(w[1:] * mod_2pi(np.diff(np.angle(R)))) ## eq (8)
class Depuncturer(object):
def __init__(self, repeat=1, puncture_pattern=['1','1']):
assert(repeat >= 1)
self._repeat = repeat
self._num_patterns = num_patterns = len(puncture_pattern)
assert(num_patterns >= 2)
assert(all([len(puncture_pattern[0]) == len(p) for p in puncture_pattern[1:]]))
m = np.array([x=='1' for y in puncture_pattern for x in y])
self._num_unpacked = len(m)
self._num_packed = np.sum(m)
self._pattern = m.reshape(num_patterns, self._num_unpacked//num_patterns).transpose().reshape(1, self._num_unpacked)[0]
self._range_packed = np.arange(self._num_packed)
self._range_unpacked = np.arange(self._num_unpacked)
def process(self, x):
n = len(x)
assert(n%(self._num_packed * self._repeat) == 0)
## (1) unpack
xd = np.zeros(n * self._num_unpacked // self._num_packed, dtype=np.float64)
i = 0
j = 0
while i < len(xd):
xd[(i + self._range_unpacked)[self._pattern]] += x[j + self._range_packed]
j += self._num_packed
i += self._num_unpacked
assert(j == n)
assert(i == len(xd))
if self._repeat == 1:
return xd
## (2) combine repeated data
xu = np.zeros(len(xd) // self._repeat, dtype=np.float64)
i = 0
j = 0
m = self._num_patterns
r = np.arange(m)
while i < len(xu):
for k in range(self._repeat):
xu[i + r] += xd[j + r]
j += m
i += m
assert(i == len(xu))
assert(j == len(xd))
return xu
if __name__ == '__main__':
idx=np.arange(3)
z=np.exp(1j*idx*0.056+1j)
print(freq_est(z)/0.056)

View File

@ -54,6 +54,7 @@ class physical_layer_driver(gr.hier_block2):
## TODO: get rrc tap information from physical layer description
self._rrc_taps = filter.firdes.root_raised_cosine(1.0, samp_rate, samp_rate/sps, 0.35, 11*sps)
preamble_offset,preamble_samples = self._physical_layer_driver_description.get_preamble_z()
preamble_length = self._sps * len(self._physical_layer_driver_description.get_preamble()) ## len(preamble_samples)
preamble_length = len(preamble_samples)
self._rrc_filter = filter.fir_filter_ccc(1, (self._rrc_taps))
self._corr_est = digital.corr_est_cc(symbols = (preamble_samples.tolist()),
@ -88,7 +89,9 @@ class physical_layer_driver(gr.hier_block2):
self.message_port_register_hier_out('soft_dec')
self.msg_connect((self._adaptive_filter, 'soft_dec'), (self, 'soft_dec'))
self.msg_connect((self._msg_proxy, 'soft_dec'), (self, 'soft_dec'))
self.message_port_register_hier_out('bits')
self.msg_connect((self._msg_proxy, 'bits'), (self, 'bits'))
def set_mu(self, mu):
self._adaptive_filter.set_mu(mu)