def test_qpsk_channel(self): upper_bound = tuple(50.0 * numpy.ones((self.num_data, ))) lower_bound = tuple(0.0 * numpy.zeros((self.num_data, ))) self.cons = cons = digital.constellation_qpsk().base() self.data = data = [ random.randrange(len(cons.points())) for x in range(self.num_data) ] self.symbols = symbols = numpy.squeeze( [cons.map_to_points_v(i) for i in data]) chan = channels.channel_model(noise_voltage=0.1, frequency_offset=0.0, epsilon=1.0, taps=[1.0 + 0.0j], noise_seed=0, block_tags=False) evm = digital.meas_evm_cc(cons, digital.evm_measurement_t_EVM_PERCENT) vso = blocks.vector_source_c(symbols, False, 1, []) mc = blocks.multiply_const_cc(3.0 + 2.0j) vsi = blocks.vector_sink_f() self.tb.connect(vso, chan, evm, vsi) self.tb.run() # check data output_data = vsi.data() self.assertLess(output_data, upper_bound) self.assertGreater(output_data, lower_bound)
def test_qpsk_3tap_lms_training(self): # set up fg gain = 0.01 # LMS gain num_taps = 16 num_samp = 2000 num_test = 500 cons = digital.constellation_qpsk().base() rxmod = digital.generic_mod(cons, False, self.sps, True, self.eb, False, False) modulated_sync_word_pre = digital.modulate_vector_bc( rxmod.to_basic_block(), self.preamble + self.preamble, [1]) modulated_sync_word = modulated_sync_word_pre[86:( 512 + 86)] # compensate for the RRC filter delay corr_max = numpy.abs( numpy.dot(modulated_sync_word, numpy.conj(modulated_sync_word))) corr_calc = self.corr_thresh / (corr_max * corr_max) preamble_symbols = self.map_symbols_to_constellation( self.unpack_values(self.preamble, 8, 2), cons) alg = digital.adaptive_algorithm_lms(cons, gain).base() evm = digital.meas_evm_cc(cons, digital.evm_measurement_t.EVM_PERCENT) leq = digital.linear_equalizer(num_taps, self.sps, alg, False, preamble_symbols, 'corr_est') correst = digital.corr_est_cc(modulated_sync_word, self.sps, 12, corr_calc, digital.THRESHOLD_ABSOLUTE) constmod = digital.generic_mod(constellation=cons, differential=False, samples_per_symbol=4, pre_diff_code=True, excess_bw=0.35, verbose=False, log=False) chan = channels.channel_model(noise_voltage=0.0, frequency_offset=0.0, epsilon=1.0, taps=(1.0 + 1.0j, 0.63 - .22j, -.1 + .07j), noise_seed=0, block_tags=False) vso = blocks.vector_source_b(self.preamble + self.data, True, 1, []) head = blocks.head(gr.sizeof_float * 1, num_samp) vsi = blocks.vector_sink_f() self.tb.connect(vso, constmod, chan, correst, leq, evm, head, vsi) self.tb.run() # look at the last 1000 samples, should converge quickly, below 5% EVM upper_bound = list(20.0 * numpy.ones((num_test, ))) lower_bound = list(0.0 * numpy.zeros((num_test, ))) output_data = vsi.data() output_data = output_data[-num_test:] self.assertLess(output_data, upper_bound) self.assertGreater(output_data, lower_bound)
def test_qpsk_nonzeroevm(self): # set up fg expected_result = tuple(numpy.zeros((self.num_data, ))) self.cons = cons = digital.constellation_qpsk().base() self.data = data = [ random.randrange(len(cons.points())) for x in range(self.num_data) ] self.symbols = symbols = numpy.squeeze( [cons.map_to_points_v(i) for i in data]) evm = digital.meas_evm_cc(cons, digital.evm_measurement_t_EVM_PERCENT) vso = blocks.vector_source_c(symbols, False, 1, []) mc = blocks.multiply_const_cc(3.0 + 2.0j) vsi = blocks.vector_sink_f() self.tb.connect(vso, mc, evm, vsi) self.tb.run() # check data output_data = vsi.data() self.assertNotEqual(expected_result, output_data)
def test_qpsk_3tap_lms_training(self): # set up fg gain = 0.001 # LMS gain num_taps_fwd = 13 num_taps_rev = 3 num_test = 1000 cons = digital.constellation_qpsk().base() rxmod = digital.generic_mod(cons, False, self.sps, True, self.eb, False, False) modulated_sync_word_pre = digital.modulate_vector_bc( rxmod.to_basic_block(), self.preamble + self.preamble, [1]) # compensate for the RRC filter delay modulated_sync_word = modulated_sync_word_pre[86:(512 + 86)] corr_max = numpy.abs( numpy.dot(modulated_sync_word, numpy.conj(modulated_sync_word))) corr_calc = self.corr_thresh / (corr_max * corr_max) preamble_symbols = self.map_symbols_to_constellation( self.unpack_values(self.preamble, 8, 2), cons) alg = digital.adaptive_algorithm_lms(cons, gain).base() evm = digital.meas_evm_cc(cons, digital.evm_measurement_t.EVM_PERCENT) dfe = digital.decision_feedback_equalizer(num_taps_fwd, num_taps_rev, self.sps, alg, True, preamble_symbols, 'corr_est') correst = digital.corr_est_cc(modulated_sync_word, self.sps, 12, corr_calc, digital.THRESHOLD_ABSOLUTE) constmod = digital.generic_mod(constellation=cons, differential=False, samples_per_symbol=4, pre_diff_code=True, excess_bw=0.35, verbose=False, log=False) chan = channels.channel_model( noise_voltage=self.noise_voltage, frequency_offset=0.0, epsilon=1.0, taps=(2.0, -0.459489 + -0.156287j, 0.185799 + 0.022878j, 0.060229 + 0.002171j, -0.023041 + -0.016539j, -0.004507 + 0.011984j, -0.002597 + 0.002675j, 0.002320 + 0.000621j, -0.001420 + -0.000126j, -0.000118 + -0.000520j, -0.000029 + -0.000201j, 0.000060 + -0.000002j, 0.169089 + -0.500778j, 0.419112 + 0.042402j, -0.139208 + 0.030027j, -0.080077 + 0.036473j, 0.026689 + 0.000837j, -0.002449 + 0.002320j, -0.000567 + -0.002068j, 0.001528 + 0.002867j, 0.000944 + -0.000166j, 0.000218 + 0.000007j, 0.000214 + -0.000150j, 0.000004 + 0.000008j), noise_seed=-44982235, block_tags=False) repeating_data = self.preamble + self.data * 200 vso = blocks.vector_source_b(repeating_data, False, 1, []) head = blocks.head(gr.sizeof_char * 1, 500) vsi = blocks.vector_sink_f() self.tb.connect(vso, head, constmod, chan, correst, dfe, evm, vsi) self.tb.run() # look at the last 1000 samples, should converge quickly, below 5% EVM upper_bound = list(20.0 * numpy.ones((num_test, ))) lower_bound = list(0.0 * numpy.zeros((num_test, ))) output_data = vsi.data() output_data = output_data[-num_test:] self.assertLess(output_data, upper_bound) self.assertGreater(output_data, lower_bound)