def __init__(self, constellation_points=_def_constellation_points, gray_coded=_def_gray_coded, *args, **kwargs): """ Hierarchical block for RRC-filtered QPSK modulation. The input is a byte stream (unsigned char) and the output is the complex modulated signal at baseband. See generic_mod block for list of parameters. """ constellation_points = _def_constellation_points constellation = digital_swig.constellation_qpsk() if constellation_points != 4: raise ValueError("QPSK can only have 4 constellation points.") if not gray_coded: raise ValueError( "This QPSK mod/demod works only for gray-coded constellations." ) super(qpsk_mod, self).__init__(constellation=constellation, gray_coded=gray_coded, *args, **kwargs)
def qpsk_constellation(mod_code=_def_mod_code): """ Creates a QPSK constellation. """ if mod_code != mod_codes.GRAY_CODE: raise ValueError("This QPSK mod/demod works only for gray-coded constellations.") return digital.constellation_qpsk()
def test_002_static_wo_tags (self): fft_len = 8 # 4 5 6 7 0 1 2 3 tx_data = [-1, -1, 1, 2, -1, 3, 0, -1, # 0 -1, -1, 0, 2, -1, 2, 0, -1, # 8 -1, -1, 3, 0, -1, 1, 0, -1, # 16 (Pilot symbols) -1, -1, 1, 1, -1, 0, 2, -1] # 24 cnst = digital.constellation_qpsk() tx_signal = [cnst.map_to_points_v(x)[0] if x != -1 else 0 for x in tx_data] occupied_carriers = ((1, 2, 6, 7),) pilot_carriers = ((), (), (1, 2, 6, 7), ()) pilot_symbols = ( [], [], [cnst.map_to_points_v(x)[0] for x in (1, 0, 3, 0)], [] ) equalizer = digital.ofdm_equalizer_static(fft_len, occupied_carriers, pilot_carriers, pilot_symbols) channel = [ 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, # These coefficients will be rotated slightly... 0, 0, 1j, 1j, 0, 1j, 1j, 0, # Go crazy here! 0, 0, 1j, 1j, 0, 1j, 1j, 0 # ...and again here. ] for idx in range(fft_len, 2*fft_len): channel[idx] = channel[idx-fft_len] * numpy.exp(1j * .1 * numpy.pi * (numpy.random.rand()-.5)) idx2 = idx+2*fft_len channel[idx2] = channel[idx2] * numpy.exp(1j * 0 * numpy.pi * (numpy.random.rand()-.5)) src = blocks.vector_source_c(numpy.multiply(tx_signal, channel), False, fft_len) sink = blocks.vector_sink_c(fft_len) eq = digital.ofdm_frame_equalizer_vcvc(equalizer.base(), 0, "", False, 4) self.tb.connect(src, eq, sink) self.tb.run () rx_data = [cnst.decision_maker_v((x,)) if x != 0 else -1 for x in sink.data()] self.assertEqual(tx_data, rx_data)
def test_002_static_wo_tags (self): fft_len = 8 # 4 5 6 7 0 1 2 3 tx_data = [-1, -1, 1, 2, -1, 3, 0, -1, # 0 -1, -1, 0, 2, -1, 2, 0, -1, # 8 -1, -1, 3, 0, -1, 1, 0, -1, # 16 (Pilot symbols) -1, -1, 1, 1, -1, 0, 2, -1] # 24 cnst = digital.constellation_qpsk() tx_signal = [cnst.map_to_points_v(x)[0] if x != -1 else 0 for x in tx_data] occupied_carriers = ((1, 2, 6, 7),) pilot_carriers = ((), (), (1, 2, 6, 7), ()) pilot_symbols = ( [], [], [cnst.map_to_points_v(x)[0] for x in (1, 0, 3, 0)], [] ) equalizer = digital.ofdm_equalizer_static(fft_len, occupied_carriers, pilot_carriers, pilot_symbols) channel = [ 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, # These coefficients will be rotated slightly... 0, 0, 1j, 1j, 0, 1j, 1j, 0, # Go crazy here! 0, 0, 1j, 1j, 0, 1j, 1j, 0 # ...and again here. ] for idx in range(fft_len, 2*fft_len): channel[idx] = channel[idx-fft_len] * numpy.exp(1j * .1 * numpy.pi * (numpy.random.rand()-.5)) idx2 = idx+2*fft_len channel[idx2] = channel[idx2] * numpy.exp(1j * 0 * numpy.pi * (numpy.random.rand()-.5)) src = gr.vector_source_c(numpy.multiply(tx_signal, channel), False, fft_len) eq = digital.ofdm_frame_equalizer_vcvc(equalizer.base(), "", False, 4) sink = gr.vector_sink_c(fft_len) self.tb.connect(src, eq, sink) self.tb.run () rx_data = [cnst.decision_maker_v((x,)) if x != 0 else -1 for x in sink.data()] self.assertEqual(tx_data, rx_data)
def _get_constellation(bps): """ Returns a modulator block for a given number of bits per symbol """ constellation = {1: digital.constellation_bpsk(), 2: digital.constellation_qpsk(), 3: digital.constellation_8psk()} try: return constellation[bps] except KeyError: print "Modulation not supported." exit(1)
def test_001_identity(self): # Constant modulus signal so no adjustments const = digital_swig.constellation_qpsk() src_data = const.points() * 1000 N = 100 # settling time expected_data = src_data[N:] result = self.transform(src_data, 0.1, const)[N:] self.assertComplexTuplesAlmostEqual(expected_data, result, 5)
def test_001_identity(self): # Constant modulus signal so no adjustments const = digital_swig.constellation_qpsk() src_data = const.points()*1000 N = 100 # settling time expected_data = src_data[N:] result = self.transform(src_data, 0.1, const)[N:] self.assertComplexTuplesAlmostEqual(expected_data, result, 5)
def _get_constellation(bps): """ Returns a modulator block for a given number of bits per symbol """ constellation = { 1: digital.constellation_bpsk(), 2: digital.constellation_qpsk(), 3: digital.constellation_8psk() } try: return constellation[bps] except KeyError: print 'Modulation not supported.' exit(1)
def __init__(self, mod_code=_def_mod_code, differential=False, *args, **kwargs): pre_diff_code = True if not differential: constellation = digital.constellation_qpsk() if mod_code != mod_codes.GRAY_CODE: raise ValueError("This QPSK mod/demod works only for gray-coded constellations.") else: constellation = digital.constellation_dqpsk() if mod_code not in set([mod_codes.GRAY_CODE, mod_codes.NO_CODE]): raise ValueError("That mod_code is not supported for DQPSK mod/demod.") if mod_code == mod_codes.NO_CODE: pre_diff_code = False super(qpsk_mod, self).__init__(constellation=constellation, pre_diff_code=pre_diff_code, *args, **kwargs)
def test_002_simpledfe (self): """ Use the simple DFE equalizer. """ fft_len = 8 # 4 5 6 7 0 1 2 3 tx_data = [-1, -1, 1, 2, -1, 3, 0, -1, # 0 -1, -1, 0, 2, -1, 2, 0, -1, # 8 -1, -1, 3, 0, -1, 1, 0, -1, # 16 (Pilot symbols) -1, -1, 1, 1, -1, 0, 2, -1] # 24 cnst = digital.constellation_qpsk() tx_signal = [cnst.map_to_points_v(x)[0] if x != -1 else 0 for x in tx_data] occupied_carriers = ((1, 2, 6, 7),) pilot_carriers = ((), (), (1, 2, 6, 7), ()) pilot_symbols = ( [], [], [cnst.map_to_points_v(x)[0] for x in (1, 0, 3, 0)], [] ) equalizer = digital.ofdm_equalizer_simpledfe( fft_len, cnst.base(), occupied_carriers, pilot_carriers, pilot_symbols, 0, 0.01 ) channel = [ 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, # These coefficients will be rotated slightly... 0, 0, 1j, 1j, 0, 1j, 1j, 0, # Go crazy here! 0, 0, 1j, 1j, 0, 1j, 1j, 0 # ...and again here. ] for idx in range(fft_len, 2*fft_len): channel[idx] = channel[idx-fft_len] * numpy.exp(1j * .1 * numpy.pi * (numpy.random.rand()-.5)) idx2 = idx+2*fft_len channel[idx2] = channel[idx2] * numpy.exp(1j * 0 * numpy.pi * (numpy.random.rand()-.5)) len_tag_key = "frame_len" len_tag = gr.gr_tag_t() len_tag.offset = 0 len_tag.key = pmt.pmt_string_to_symbol(len_tag_key) len_tag.value = pmt.pmt_from_long(4) chan_tag = gr.gr_tag_t() chan_tag.offset = 0 chan_tag.key = pmt.pmt_string_to_symbol("ofdm_sync_chan_taps") chan_tag.value = pmt.pmt_init_c32vector(fft_len, channel[:fft_len]) src = gr.vector_source_c(numpy.multiply(tx_signal, channel), False, fft_len, (len_tag, chan_tag)) eq = digital.ofdm_frame_equalizer_vcvc(equalizer.base(), 0, len_tag_key, True) sink = gr.vector_sink_c(fft_len) self.tb.connect(src, eq, sink) self.tb.run () rx_data = [cnst.decision_maker_v((x,)) if x != 0 else -1 for x in sink.data()] self.assertEqual(tx_data, rx_data) for tag in sink.tags(): if pmt.pmt_symbol_to_string(tag.key) == len_tag_key: self.assertEqual(pmt.pmt_to_long(tag.value), 4) if pmt.pmt_symbol_to_string(tag.key) == "ofdm_sync_chan_taps": self.assertComplexTuplesAlmostEqual(list(pmt.pmt_c32vector_elements(tag.value)), channel[-fft_len:], places=1)
def test_002_simpledfe (self): """ Use the simple DFE equalizer. """ fft_len = 8 # 4 5 6 7 0 1 2 3 tx_data = [-1, -1, 1, 2, -1, 3, 0, -1, # 0 -1, -1, 0, 2, -1, 2, 0, -1, # 8 -1, -1, 3, 0, -1, 1, 0, -1, # 16 (Pilot symbols) -1, -1, 1, 1, -1, 0, 2, -1] # 24 cnst = digital.constellation_qpsk() tx_signal = [cnst.map_to_points_v(x)[0] if x != -1 else 0 for x in tx_data] occupied_carriers = ((1, 2, 6, 7),) pilot_carriers = ((), (), (1, 2, 6, 7), ()) pilot_symbols = ( [], [], [cnst.map_to_points_v(x)[0] for x in (1, 0, 3, 0)], [] ) equalizer = digital.ofdm_equalizer_simpledfe( fft_len, cnst.base(), occupied_carriers, pilot_carriers, pilot_symbols, 0, 0.01 ) channel = [ 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, # These coefficients will be rotated slightly... 0, 0, 1j, 1j, 0, 1j, 1j, 0, # Go crazy here! 0, 0, 1j, 1j, 0, 1j, 1j, 0 # ...and again here. ] for idx in range(fft_len, 2*fft_len): channel[idx] = channel[idx-fft_len] * numpy.exp(1j * .1 * numpy.pi * (numpy.random.rand()-.5)) idx2 = idx+2*fft_len channel[idx2] = channel[idx2] * numpy.exp(1j * 0 * numpy.pi * (numpy.random.rand()-.5)) len_tag_key = "frame_len" len_tag = gr.tag_t() len_tag.offset = 0 len_tag.key = pmt.string_to_symbol(len_tag_key) len_tag.value = pmt.from_long(4) chan_tag = gr.tag_t() chan_tag.offset = 0 chan_tag.key = pmt.string_to_symbol("ofdm_sync_chan_taps") chan_tag.value = pmt.init_c32vector(fft_len, channel[:fft_len]) src = blocks.vector_source_c(numpy.multiply(tx_signal, channel), False, fft_len, (len_tag, chan_tag)) eq = digital.ofdm_frame_equalizer_vcvc(equalizer.base(), 0, len_tag_key, True) sink = blocks.vector_sink_c(fft_len) self.tb.connect(src, eq, sink) self.tb.run () rx_data = [cnst.decision_maker_v((x,)) if x != 0 else -1 for x in sink.data()] self.assertEqual(tx_data, rx_data) for tag in sink.tags(): if pmt.symbol_to_string(tag.key) == len_tag_key: self.assertEqual(pmt.to_long(tag.value), 4) if pmt.symbol_to_string(tag.key) == "ofdm_sync_chan_taps": self.assertComplexTuplesAlmostEqual(list(pmt.c32vector_elements(tag.value)), channel[-fft_len:], places=1)
def _test_constellation_decoder_cb_qpsk(self): cnst = digital.constellation_qpsk() src_data = (0.5 + 0.5j, 0.1 - 1.2j, -0.8 - 0.1j, -0.45 + 0.8j, 0.8 + 1.0j, -0.5 + 0.1j, 0.1 - 1.2j) expected_result = (3, 1, 0, 2, 3, 2, 1) src = blocks.vector_source_c(src_data) op = digital_swig.constellation_decoder_cb(cnst.base()) dst = blocks.vector_sink_b() self.tb.connect(src, op) self.tb.connect(op, dst) self.tb.run() # run the graph and wait for it to finish actual_result = dst.data() # fetch the contents of the sink # print "actual result", actual_result # print "expected result", expected_result self.assertFloatTuplesAlmostEqual(expected_result, actual_result)
def test_002_static_wo_tags (self): """ Same as before, but the input stream has no tag. We specify the frame size in the constructor. We also specify a tag key, so the output stream *should* have a length tag. """ fft_len = 8 n_syms = 4 # 4 5 6 7 0 1 2 3 tx_data = [-1, -1, 1, 2, -1, 3, 0, -1, # 0 -1, -1, 0, 2, -1, 2, 0, -1, # 8 -1, -1, 3, 0, -1, 1, 0, -1, # 16 (Pilot symbols) -1, -1, 1, 1, -1, 0, 2, -1] # 24 cnst = digital.constellation_qpsk() tx_signal = [cnst.map_to_points_v(x)[0] if x != -1 else 0 for x in tx_data] occupied_carriers = ((1, 2, 6, 7),) pilot_carriers = ((), (), (1, 2, 6, 7), ()) pilot_symbols = ( [], [], [cnst.map_to_points_v(x)[0] for x in (1, 0, 3, 0)], [] ) equalizer = digital.ofdm_equalizer_static(fft_len, occupied_carriers, pilot_carriers, pilot_symbols) channel = [ 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, # These coefficients will be rotated slightly (below)... 0, 0, 1j, 1j, 0, 1j, 1j, 0, # Go crazy here! 0, 0, 1j, 1j, 0, 1j, 1j, 0 # ...and again here. ] for idx in range(fft_len, 2*fft_len): channel[idx] = channel[idx-fft_len] * numpy.exp(1j * .1 * numpy.pi * (numpy.random.rand()-.5)) idx2 = idx+2*fft_len channel[idx2] = channel[idx2] * numpy.exp(1j * 0 * numpy.pi * (numpy.random.rand()-.5)) src = gr.vector_source_c(numpy.multiply(tx_signal, channel), False, fft_len) # We do specify a length tag, it should then appear at the output eq = digital.ofdm_frame_equalizer_vcvc(equalizer.base(), 0, "frame_len", False, n_syms) sink = gr.vector_sink_c(fft_len) self.tb.connect(src, eq, sink) self.tb.run () rx_data = [cnst.decision_maker_v((x,)) if x != 0 else -1 for x in sink.data()] self.assertEqual(tx_data, rx_data) # Check len tag tags = sink.tags() len_tag = dict() for tag in tags: ptag = gr.tag_to_python(tag) if ptag.key == 'frame_len': len_tag[ptag.key] = ptag.value self.assertEqual(len_tag, {'frame_len': 4})
def test_002_static_wo_tags (self): """ Same as before, but the input stream has no tag. We specify the frame size in the constructor. We also specify a tag key, so the output stream *should* have a length tag. """ fft_len = 8 n_syms = 4 # 4 5 6 7 0 1 2 3 tx_data = [-1, -1, 1, 2, -1, 3, 0, -1, # 0 -1, -1, 0, 2, -1, 2, 0, -1, # 8 -1, -1, 3, 0, -1, 1, 0, -1, # 16 (Pilot symbols) -1, -1, 1, 1, -1, 0, 2, -1] # 24 cnst = digital.constellation_qpsk() tx_signal = [cnst.map_to_points_v(x)[0] if x != -1 else 0 for x in tx_data] occupied_carriers = ((1, 2, 6, 7),) pilot_carriers = ((), (), (1, 2, 6, 7), ()) pilot_symbols = ( [], [], [cnst.map_to_points_v(x)[0] for x in (1, 0, 3, 0)], [] ) equalizer = digital.ofdm_equalizer_static(fft_len, occupied_carriers, pilot_carriers, pilot_symbols) channel = [ 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, # These coefficients will be rotated slightly (below)... 0, 0, 1j, 1j, 0, 1j, 1j, 0, # Go crazy here! 0, 0, 1j, 1j, 0, 1j, 1j, 0 # ...and again here. ] for idx in range(fft_len, 2*fft_len): channel[idx] = channel[idx-fft_len] * numpy.exp(1j * .1 * numpy.pi * (numpy.random.rand()-.5)) idx2 = idx+2*fft_len channel[idx2] = channel[idx2] * numpy.exp(1j * 0 * numpy.pi * (numpy.random.rand()-.5)) src = gr.vector_source_c(numpy.multiply(tx_signal, channel), False, fft_len) # We do specify a length tag, it should then appear at the output eq = digital.ofdm_frame_equalizer_vcvc(equalizer.base(), 0, "frame_len", False, n_syms) sink = blocks.vector_sink_c(fft_len) self.tb.connect(src, eq, sink) self.tb.run () rx_data = [cnst.decision_maker_v((x,)) if x != 0 else -1 for x in sink.data()] self.assertEqual(tx_data, rx_data) # Check len tag tags = sink.tags() len_tag = dict() for tag in tags: ptag = gr.tag_to_python(tag) if ptag.key == 'frame_len': len_tag[ptag.key] = ptag.value self.assertEqual(len_tag, {'frame_len': 4})
def _test_constellation_decoder_cb_qpsk(self): cnst = digital.constellation_qpsk() src_data = (0.5 + 0.5j, 0.1 - 1.2j, -0.8 - 0.1j, -0.45 + 0.8j, 0.8 + 1.0j, -0.5 + 0.1j, 0.1 - 1.2j) expected_result = (3, 1, 0, 2, 3, 2, 1) src = blocks.vector_source_c(src_data) op = digital_swig.constellation_decoder_cb(cnst.base()) dst = blocks.vector_sink_b() self.tb.connect(src, op) self.tb.connect(op, dst) self.tb.run() # run the graph and wait for it to finish actual_result = dst.data() # fetch the contents of the sink #print "actual result", actual_result #print "expected result", expected_result self.assertFloatTuplesAlmostEqual(expected_result, actual_result)
def __init__(self, constellation_points=_def_constellation_points, *args, **kwargs): """ Hierarchical block for RRC-filtered QPSK modulation. The input is a byte stream (unsigned char) and the output is the complex modulated signal at baseband. See generic_demod block for list of parameters. """ constellation_points = _def_constellation_points constellation = digital_swig.constellation_qpsk() if constellation_points != 4: raise ValueError('Number of constellation points must be 4 for QPSK.') super(qpsk_demod, self).__init__(constellation=constellation, *args, **kwargs)
def __init__(self, constellation_points=_def_constellation_points, *args, **kwargs): """ Hierarchical block for RRC-filtered QPSK modulation. The input is a byte stream (unsigned char) and the output is the complex modulated signal at baseband. See generic_demod block for list of parameters. """ constellation_points = _def_constellation_points constellation = digital_swig.constellation_qpsk() if constellation_points != 4: raise ValueError( 'Number of constellation points must be 4 for QPSK.') super(qpsk_demod, self).__init__(constellation=constellation, *args, **kwargs)
def __init__(self, constellation_points=_def_constellation_points, gray_coded=_def_gray_coded, *args, **kwargs): """ Hierarchical block for RRC-filtered QPSK modulation. The input is a byte stream (unsigned char) and the output is the complex modulated signal at baseband. See generic_mod block for list of parameters. """ constellation_points = _def_constellation_points constellation = digital_swig.constellation_qpsk() if constellation_points != 4: raise ValueError("QPSK can only have 4 constellation points.") if not gray_coded: raise ValueError("This QPSK mod/demod works only for gray-coded constellations.") super(qpsk_mod, self).__init__(constellation=constellation, gray_coded=gray_coded, *args, **kwargs)
def test_002_static(self): """ - Add a simple channel - Make symbols QPSK """ fft_len = 8 # 4 5 6 7 0 1 2 3 tx_data = [ -1, -1, 1, 2, -1, 3, 0, -1, # 0 -1, -1, 0, 2, -1, 2, 0, -1, # 8 -1, -1, 3, 0, -1, 1, 0, -1, # 16 (Pilot symbols) -1, -1, 1, 1, -1, 0, 2, -1 ] # 24 cnst = digital.constellation_qpsk() tx_signal = [ cnst.map_to_points_v(x)[0] if x != -1 else 0 for x in tx_data ] occupied_carriers = ((1, 2, 6, 7), ) pilot_carriers = ((), (), (1, 2, 6, 7), ()) pilot_symbols = ([], [], [cnst.map_to_points_v(x)[0] for x in (1, 0, 3, 0)], []) equalizer = digital.ofdm_equalizer_static(fft_len, occupied_carriers, pilot_carriers, pilot_symbols) channel = [ 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, # These coefficients will be rotated slightly (but less than \pi/2) 0, 0, 1j, 1j, 0, 1j, 1j, 0, # Go crazy here! 0, 0, 1j, 1j, 0, 1j, 1j, 0 ] channel = [ 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, # These coefficients will be rotated slightly (but less than \pi/2) 0, 0, 1j, 1j, 0, 1j, 1j, 0, # Go crazy here! 0, 0, 1j, 1j, 0, 1j, 1j, 0 ] for idx in range(fft_len, 2 * fft_len): channel[idx] = channel[idx - fft_len] * numpy.exp( 1j * .1 * numpy.pi * (numpy.random.rand() - .5)) len_tag_key = "frame_len" len_tag = gr.gr_tag_t() len_tag.offset = 0 len_tag.key = pmt.pmt_string_to_symbol(len_tag_key) len_tag.value = pmt.pmt_from_long(4) chan_tag = gr.gr_tag_t() chan_tag.offset = 0 chan_tag.key = pmt.pmt_string_to_symbol("ofdm_sync_chan_taps") chan_tag.value = pmt.pmt_init_c32vector(fft_len, channel[:fft_len]) src = gr.vector_source_c(numpy.multiply(tx_signal, channel), False, fft_len, (len_tag, chan_tag)) eq = digital.ofdm_frame_equalizer_vcvc(equalizer.base(), 0, len_tag_key, True) sink = gr.vector_sink_c(fft_len) self.tb.connect(src, eq, sink) self.tb.run() rx_data = [ cnst.decision_maker_v((x, )) if x != 0 else -1 for x in sink.data() ] # Check data self.assertEqual(tx_data, rx_data) # Check tags tag_dict = dict() for tag in sink.tags(): ptag = gr.tag_to_python(tag) tag_dict[ptag.key] = ptag.value if ptag.key == 'ofdm_sync_chan_taps': tag_dict[ptag.key] = list(pmt.pmt_c32vector_elements( tag.value)) else: tag_dict[ptag.key] = pmt.to_python(tag.value) expected_dict = { 'frame_len': 4, 'ofdm_sync_chan_taps': channel[-fft_len:] } self.assertEqual(tag_dict, expected_dict)
def test_002_static (self): """ - Add a simple channel - Make symbols QPSK """ fft_len = 8 # 4 5 6 7 0 1 2 3 tx_data = [-1, -1, 1, 2, -1, 3, 0, -1, # 0 -1, -1, 0, 2, -1, 2, 0, -1, # 8 -1, -1, 3, 0, -1, 1, 0, -1, # 16 (Pilot symbols) -1, -1, 1, 1, -1, 0, 2, -1] # 24 cnst = digital.constellation_qpsk() tx_signal = [cnst.map_to_points_v(x)[0] if x != -1 else 0 for x in tx_data] occupied_carriers = ((1, 2, 6, 7),) pilot_carriers = ((), (), (1, 2, 6, 7), ()) pilot_symbols = ( [], [], [cnst.map_to_points_v(x)[0] for x in (1, 0, 3, 0)], [] ) equalizer = digital.ofdm_equalizer_static(fft_len, occupied_carriers, pilot_carriers, pilot_symbols) channel = [ 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, # These coefficients will be rotated slightly (but less than \pi/2) 0, 0, 1j, 1j, 0, 1j, 1j, 0, # Go crazy here! 0, 0, 1j, 1j, 0, 1j, 1j, 0 ] channel = [ 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, # These coefficients will be rotated slightly (but less than \pi/2) 0, 0, 1j, 1j, 0, 1j, 1j, 0, # Go crazy here! 0, 0, 1j, 1j, 0, 1j, 1j, 0 ] for idx in range(fft_len, 2*fft_len): channel[idx] = channel[idx-fft_len] * numpy.exp(1j * .1 * numpy.pi * (numpy.random.rand()-.5)) len_tag_key = "frame_len" len_tag = gr.gr_tag_t() len_tag.offset = 0 len_tag.key = pmt.pmt_string_to_symbol(len_tag_key) len_tag.value = pmt.pmt_from_long(4) chan_tag = gr.gr_tag_t() chan_tag.offset = 0 chan_tag.key = pmt.pmt_string_to_symbol("ofdm_sync_chan_taps") chan_tag.value = pmt.pmt_init_c32vector(fft_len, channel[:fft_len]) src = gr.vector_source_c(numpy.multiply(tx_signal, channel), False, fft_len, (len_tag, chan_tag)) eq = digital.ofdm_frame_equalizer_vcvc(equalizer.base(), 0, len_tag_key, True) sink = gr.vector_sink_c(fft_len) self.tb.connect(src, eq, sink) self.tb.run () rx_data = [cnst.decision_maker_v((x,)) if x != 0 else -1 for x in sink.data()] # Check data self.assertEqual(tx_data, rx_data) # Check tags tag_dict = dict() for tag in sink.tags(): ptag = gr.tag_to_python(tag) tag_dict[ptag.key] = ptag.value if ptag.key == 'ofdm_sync_chan_taps': tag_dict[ptag.key] = list(pmt.pmt_c32vector_elements(tag.value)) else: tag_dict[ptag.key] = pmt.to_python(tag.value) expected_dict = { 'frame_len': 4, 'ofdm_sync_chan_taps': channel[-fft_len:] } self.assertEqual(tag_dict, expected_dict)
import os from gnuradio import gr, gr_unittest import trellis_swig as trellis import digital_swig as digital import analog_swig as analog import blocks_swig as blocks fsm_args = { "awgn1o2_4": (2, 4, 4, (0, 2, 0, 2, 1, 3, 1, 3), (0, 3, 3, 0, 1, 2, 2, 1)), "rep2": (2, 1, 4, (0, 0), (0, 3)), "nothing": (2, 1, 2, (0, 0), (0, 1)), } constells = {2: digital.constellation_bpsk(), 4: digital.constellation_qpsk()} class test_trellis(gr_unittest.TestCase): def test_001_fsm(self): f = trellis.fsm(*fsm_args["awgn1o2_4"]) self.assertEqual(fsm_args["awgn1o2_4"], (f.I(), f.S(), f.O(), f.NS(), f.OS())) def test_002_fsm(self): f = trellis.fsm(*fsm_args["awgn1o2_4"]) g = trellis.fsm(f) self.assertEqual((g.I(), g.S(), g.O(), g.NS(), g.OS()), (f.I(), f.S(), f.O(), f.NS(), f.OS())) def test_003_fsm(self): # FIXME: no file "awgn1o2_4.fsm" # f = trellis.fsm("awgn1o2_4.fsm")
def qpsk_constellation(m=_def_constellation_points): if m != _def_constellation_points: raise ValueError("QPSK can only have 4 constellation points.") return digital_swig.constellation_qpsk()
# but because it runs on the non-installed python code it's all a mess. import trellis import os import digital_swig fsm_args = {"awgn1o2_4": (2, 4, 4, (0, 2, 0, 2, 1, 3, 1, 3), (0, 3, 3, 0, 1, 2, 2, 1), ), "rep2": (2, 1, 4, (0, 0), (0, 3)), "nothing": (2, 1, 2, (0, 0), (0, 1)), } constells = {2: digital_swig.constellation_bpsk(), 4: digital_swig.constellation_qpsk(), } class test_trellis (gr_unittest.TestCase): def test_001_fsm (self): f = trellis.fsm(*fsm_args["awgn1o2_4"]) self.assertEqual(fsm_args["awgn1o2_4"],(f.I(),f.S(),f.O(),f.NS(),f.OS())) def test_002_fsm (self): f = trellis.fsm(*fsm_args["awgn1o2_4"]) g = trellis.fsm(f) self.assertEqual((g.I(),g.S(),g.O(),g.NS(),g.OS()),(f.I(),f.S(),f.O(),f.NS(),f.OS())) def test_003_fsm (self): # FIXME: no file "awgn1o2_4.fsm"
fsm_args = { "awgn1o2_4": ( 2, 4, 4, (0, 2, 0, 2, 1, 3, 1, 3), (0, 3, 3, 0, 1, 2, 2, 1), ), "rep2": (2, 1, 4, (0, 0), (0, 3)), "nothing": (2, 1, 2, (0, 0), (0, 1)), } constells = { 2: digital_swig.constellation_bpsk(), 4: digital_swig.constellation_qpsk(), } class test_trellis(gr_unittest.TestCase): def test_001_fsm(self): f = trellis.fsm(*fsm_args["awgn1o2_4"]) self.assertEqual(fsm_args["awgn1o2_4"], (f.I(), f.S(), f.O(), f.NS(), f.OS())) def test_002_fsm(self): f = trellis.fsm(*fsm_args["awgn1o2_4"]) g = trellis.fsm(f) self.assertEqual((g.I(), g.S(), g.O(), g.NS(), g.OS()), (f.I(), f.S(), f.O(), f.NS(), f.OS()))
fsm_args = { "awgn1o2_4": ( 2, 4, 4, (0, 2, 0, 2, 1, 3, 1, 3), (0, 3, 3, 0, 1, 2, 2, 1), ), "rep2": (2, 1, 4, (0, 0), (0, 3)), "nothing": (2, 1, 2, (0, 0), (0, 1)), } constells = { 2: digital.constellation_bpsk(), 4: digital.constellation_qpsk(), } class test_trellis(gr_unittest.TestCase): def test_001_fsm(self): f = trellis.fsm(*fsm_args["awgn1o2_4"]) self.assertEqual(fsm_args["awgn1o2_4"], (f.I(), f.S(), f.O(), f.NS(), f.OS())) def test_002_fsm(self): f = trellis.fsm(*fsm_args["awgn1o2_4"]) g = trellis.fsm(f) self.assertEqual((g.I(), g.S(), g.O(), g.NS(), g.OS()), (f.I(), f.S(), f.O(), f.NS(), f.OS()))