Add BER simulations

This commit is contained in:
jaseg 2020-02-06 23:14:55 +01:00
parent 7740868444
commit ff366e3377
25 changed files with 76418 additions and 3 deletions

892
BER Plots.ipynb Normal file

File diff suppressed because one or more lines are too long

220
dec_proto_am_ber_top.py Executable file
View file

@ -0,0 +1,220 @@
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
##################################################
# GNU Radio Python Flow Graph
# Title: Dec Proto Am Ber Top
# GNU Radio version: 3.7.13.5
##################################################
from gnuradio import analog
from gnuradio import blocks
from gnuradio import digital
from gnuradio import eng_notation
from gnuradio import fec
from gnuradio import filter
from gnuradio import gr
from gnuradio.eng_option import eng_option
from gnuradio.filter import firdes
from optparse import OptionParser
import pmt
class dec_proto_am_ber_top(gr.top_block):
def __init__(self, ber_file='0', carrier=1, mod_depth=0.8, signal_strength=2):
gr.top_block.__init__(self, "Dec Proto Am Ber Top")
##################################################
# Parameters
##################################################
self.ber_file = ber_file
self.carrier = carrier
self.mod_depth = mod_depth
self.signal_strength = signal_strength
##################################################
# Variables
##################################################
self.sim_mul = sim_mul = 1e4
self.actual_sampling_rate = actual_sampling_rate = 10
self.sync_tag = sync_tag = gr.tag_utils.python_to_tag((0, pmt.intern("sync"), pmt.from_double(0.0), pmt.intern("correlate_access_code")))
self.samp_rate = samp_rate = actual_sampling_rate*sim_mul
self.pi = pi = 3.141592653589793
self.packet_time_est_tag = packet_time_est_tag = gr.tag_utils.python_to_tag((0, pmt.intern("start"), pmt.from_double(0.0), pmt.intern("packet_vector_source")))
##################################################
# Blocks
##################################################
self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass(
1.0/signal_strength*1000 * 2, samp_rate, 0.2 * sim_mul, 0.05 * sim_mul, firdes.WIN_HAMMING, 6.76))
self.fec_ber_bf_0 = fec.ber_bf(False, 0, -7.0)
self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(50, 0.001, 0, 0.01, 0.01)
self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb()
self.blocks_vector_source_x_0_0_1_0 = blocks.vector_source_f([1,0]*(4*12)+[1,1,0,1,0,1,0,1]*12+[1,0,1,1,1,1,1,0,0,1]+[1,1,1,1,0,1,1,0,0,1]+[1,0,1,1,1,1,1,0,0,1]+[0,1,1,1,0,1,1,0,1,0]+[0,0,0,0,0,1,0,1,0,1,1,0,0,1,1,1,0,0,0,0]+[0]*128, True, 1, [packet_time_est_tag])
self.blocks_throttle_0 = blocks.throttle(gr.sizeof_float*1, samp_rate,True)
self.blocks_repeat_0 = blocks.repeat(gr.sizeof_float*1, 10*5)
self.blocks_null_source_1 = blocks.null_source(gr.sizeof_float*1)
self.blocks_multiply_xx_0_0 = blocks.multiply_vff(1)
self.blocks_multiply_xx_0 = blocks.multiply_vcc(1)
self.blocks_multiply_const_vxx_1 = blocks.multiply_const_vff((mod_depth, ))
self.blocks_multiply_const_vxx_0 = blocks.multiply_const_vcc((1.0/mod_depth, ))
self.blocks_float_to_complex_0 = blocks.float_to_complex(1)
self.blocks_float_to_char_0 = blocks.float_to_char(1, 1)
self.blocks_file_source_0 = blocks.file_source(gr.sizeof_float*1, '/home/user/research/smart_meter_reset/gm_platform/fw/raw_freq.bin', True)
self.blocks_file_source_0.set_begin_tag(pmt.PMT_NIL)
self.blocks_file_sink_0 = blocks.file_sink(gr.sizeof_float*1, ber_file, False)
self.blocks_file_sink_0.set_unbuffered(False)
self.blocks_delay_0 = blocks.delay(gr.sizeof_float*1, 5)
self.blocks_complex_to_mag_0 = blocks.complex_to_mag(1)
self.blocks_add_xx_0 = blocks.add_vff(1)
self.blocks_add_const_vxx_2_0 = blocks.add_const_vff((-0.5, ))
self.blocks_add_const_vxx_2 = blocks.add_const_vcc((-(1-mod_depth), ))
self.blocks_add_const_vxx_1 = blocks.add_const_vff((1-mod_depth, ))
self.blocks_add_const_vxx_0 = blocks.add_const_vff((-50, ))
self.analog_sig_source_x_0_0 = analog.sig_source_f(samp_rate, analog.GR_COS_WAVE, carrier * sim_mul, signal_strength*1e-3, 0)
self.analog_sig_source_x_0 = analog.sig_source_c(samp_rate, analog.GR_COS_WAVE, -carrier * sim_mul, 1, 0)
##################################################
# Connections
##################################################
self.connect((self.analog_sig_source_x_0, 0), (self.blocks_multiply_xx_0, 1))
self.connect((self.analog_sig_source_x_0_0, 0), (self.blocks_multiply_xx_0_0, 1))
self.connect((self.blocks_add_const_vxx_0, 0), (self.blocks_add_xx_0, 0))
self.connect((self.blocks_add_const_vxx_1, 0), (self.blocks_multiply_xx_0_0, 0))
self.connect((self.blocks_add_const_vxx_2, 0), (self.blocks_multiply_const_vxx_0, 0))
self.connect((self.blocks_add_const_vxx_2_0, 0), (self.digital_clock_recovery_mm_xx_0, 0))
self.connect((self.blocks_add_xx_0, 0), (self.blocks_float_to_complex_0, 0))
self.connect((self.blocks_complex_to_mag_0, 0), (self.blocks_add_const_vxx_2_0, 0))
self.connect((self.blocks_delay_0, 0), (self.blocks_float_to_char_0, 0))
self.connect((self.blocks_file_source_0, 0), (self.blocks_throttle_0, 0))
self.connect((self.blocks_float_to_char_0, 0), (self.fec_ber_bf_0, 1))
self.connect((self.blocks_float_to_complex_0, 0), (self.blocks_multiply_xx_0, 0))
self.connect((self.blocks_multiply_const_vxx_0, 0), (self.blocks_complex_to_mag_0, 0))
self.connect((self.blocks_multiply_const_vxx_1, 0), (self.blocks_add_const_vxx_1, 0))
self.connect((self.blocks_multiply_xx_0, 0), (self.low_pass_filter_0, 0))
self.connect((self.blocks_multiply_xx_0_0, 0), (self.blocks_add_xx_0, 1))
self.connect((self.blocks_null_source_1, 0), (self.blocks_float_to_complex_0, 1))
self.connect((self.blocks_repeat_0, 0), (self.blocks_multiply_const_vxx_1, 0))
self.connect((self.blocks_throttle_0, 0), (self.blocks_add_const_vxx_0, 0))
self.connect((self.blocks_vector_source_x_0_0_1_0, 0), (self.blocks_delay_0, 0))
self.connect((self.blocks_vector_source_x_0_0_1_0, 0), (self.blocks_repeat_0, 0))
self.connect((self.digital_binary_slicer_fb_0, 0), (self.fec_ber_bf_0, 0))
self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.digital_binary_slicer_fb_0, 0))
self.connect((self.fec_ber_bf_0, 0), (self.blocks_file_sink_0, 0))
self.connect((self.low_pass_filter_0, 0), (self.blocks_add_const_vxx_2, 0))
def get_ber_file(self):
return self.ber_file
def set_ber_file(self, ber_file):
self.ber_file = ber_file
self.blocks_file_sink_0.open(self.ber_file)
def get_carrier(self):
return self.carrier
def set_carrier(self, carrier):
self.carrier = carrier
self.analog_sig_source_x_0_0.set_frequency(self.carrier * self.sim_mul)
self.analog_sig_source_x_0.set_frequency(-self.carrier * self.sim_mul)
def get_mod_depth(self):
return self.mod_depth
def set_mod_depth(self, mod_depth):
self.mod_depth = mod_depth
self.blocks_multiply_const_vxx_1.set_k((self.mod_depth, ))
self.blocks_multiply_const_vxx_0.set_k((1.0/self.mod_depth, ))
self.blocks_add_const_vxx_2.set_k((-(1-self.mod_depth), ))
self.blocks_add_const_vxx_1.set_k((1-self.mod_depth, ))
def get_signal_strength(self):
return self.signal_strength
def set_signal_strength(self, signal_strength):
self.signal_strength = signal_strength
self.low_pass_filter_0.set_taps(firdes.low_pass(1.0/self.signal_strength*1000 * 2, self.samp_rate, 0.2 * self.sim_mul, 0.05 * self.sim_mul, firdes.WIN_HAMMING, 6.76))
self.analog_sig_source_x_0_0.set_amplitude(self.signal_strength*1e-3)
def get_sim_mul(self):
return self.sim_mul
def set_sim_mul(self, sim_mul):
self.sim_mul = sim_mul
self.set_samp_rate(self.actual_sampling_rate*self.sim_mul)
self.low_pass_filter_0.set_taps(firdes.low_pass(1.0/self.signal_strength*1000 * 2, self.samp_rate, 0.2 * self.sim_mul, 0.05 * self.sim_mul, firdes.WIN_HAMMING, 6.76))
self.analog_sig_source_x_0_0.set_frequency(self.carrier * self.sim_mul)
self.analog_sig_source_x_0.set_frequency(-self.carrier * self.sim_mul)
def get_actual_sampling_rate(self):
return self.actual_sampling_rate
def set_actual_sampling_rate(self, actual_sampling_rate):
self.actual_sampling_rate = actual_sampling_rate
self.set_samp_rate(self.actual_sampling_rate*self.sim_mul)
def get_sync_tag(self):
return self.sync_tag
def set_sync_tag(self, sync_tag):
self.sync_tag = sync_tag
def get_samp_rate(self):
return self.samp_rate
def set_samp_rate(self, samp_rate):
self.samp_rate = samp_rate
self.low_pass_filter_0.set_taps(firdes.low_pass(1.0/self.signal_strength*1000 * 2, self.samp_rate, 0.2 * self.sim_mul, 0.05 * self.sim_mul, firdes.WIN_HAMMING, 6.76))
self.blocks_throttle_0.set_sample_rate(self.samp_rate)
self.analog_sig_source_x_0_0.set_sampling_freq(self.samp_rate)
self.analog_sig_source_x_0.set_sampling_freq(self.samp_rate)
def get_pi(self):
return self.pi
def set_pi(self, pi):
self.pi = pi
def get_packet_time_est_tag(self):
return self.packet_time_est_tag
def set_packet_time_est_tag(self, packet_time_est_tag):
self.packet_time_est_tag = packet_time_est_tag
self.blocks_vector_source_x_0_0_1_0.set_data([1,0]*(4*12)+[1,1,0,1,0,1,0,1]*12+[1,0,1,1,1,1,1,0,0,1]+[1,1,1,1,0,1,1,0,0,1]+[1,0,1,1,1,1,1,0,0,1]+[0,1,1,1,0,1,1,0,1,0]+[0,0,0,0,0,1,0,1,0,1,1,0,0,1,1,1,0,0,0,0]+[0]*128, [self.packet_time_est_tag])
def argument_parser():
parser = OptionParser(usage="%prog: [options]", option_class=eng_option)
parser.add_option(
"", "--ber-file", dest="ber_file", type="string", default='0',
help="Set BER data output file [default=%default]")
parser.add_option(
"", "--carrier", dest="carrier", type="eng_float", default=eng_notation.num_to_str(1),
help="Set Carrier frequency in Hz [default=%default]")
parser.add_option(
"", "--mod-depth", dest="mod_depth", type="eng_float", default=eng_notation.num_to_str(0.8),
help="Set Modulation depth (0-1) [default=%default]")
parser.add_option(
"", "--signal-strength", dest="signal_strength", type="eng_float", default=eng_notation.num_to_str(2),
help="Set signal strength in mHz [default=%default]")
return parser
def main(top_block_cls=dec_proto_am_ber_top, options=None):
if options is None:
options, _ = argument_parser().parse_args()
tb = top_block_cls(ber_file=options.ber_file, carrier=options.carrier, mod_depth=options.mod_depth, signal_strength=options.signal_strength)
tb.start()
try:
raw_input('Press Enter to quit: ')
except EOFError:
pass
tb.stop()
tb.wait()
if __name__ == '__main__':
main()

191
dec_proto_am_dc_ber_top.py Executable file
View file

@ -0,0 +1,191 @@
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
##################################################
# GNU Radio Python Flow Graph
# Title: Dec Proto Am Dc Ber Top
# GNU Radio version: 3.7.13.5
##################################################
from gnuradio import blocks
from gnuradio import digital
from gnuradio import eng_notation
from gnuradio import fec
from gnuradio import filter
from gnuradio import gr
from gnuradio.eng_option import eng_option
from gnuradio.filter import firdes
from optparse import OptionParser
import pmt
class dec_proto_am_dc_ber_top(gr.top_block):
def __init__(self, ber_file='0', signal_strength=50):
gr.top_block.__init__(self, "Dec Proto Am Dc Ber Top")
##################################################
# Parameters
##################################################
self.ber_file = ber_file
self.signal_strength = signal_strength
##################################################
# Variables
##################################################
self.sim_mul = sim_mul = 1e4
self.actual_sampling_rate = actual_sampling_rate = 10
self.sync_tag = sync_tag = gr.tag_utils.python_to_tag((0, pmt.intern("sync"), pmt.from_double(0.0), pmt.intern("correlate_access_code")))
self.samp_rate = samp_rate = actual_sampling_rate*sim_mul
self.pi = pi = 3.141592653589793
self.packet_time_est_tag = packet_time_est_tag = gr.tag_utils.python_to_tag((0, pmt.intern("start"), pmt.from_double(0.0), pmt.intern("packet_vector_source")))
self.ber_delay = ber_delay = 198
##################################################
# Blocks
##################################################
self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass(
1, samp_rate, 0.1 * sim_mul, 0.05 * sim_mul, firdes.WIN_HAMMING, 6.76))
self.high_pass_filter_0 = filter.fir_filter_ccf(1, firdes.high_pass(
1, samp_rate, sim_mul/200, sim_mul/800, firdes.WIN_HAMMING, 6.76))
self.fec_ber_bf_0 = fec.ber_bf(False, 0, -7.0)
self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(50, 0.001, 0, 0.01, 0.01)
self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb()
self.blocks_vector_source_x_0_0_1_0 = blocks.vector_source_f([1,0]*(4*12)+[1,1,0,1,0,1,0,1]*12+[1,0,1,1,1,1,1,0,0,1]+[1,1,1,1,0,1,1,0,0,1]+[1,0,1,1,1,1,1,0,0,1]+[0,1,1,1,0,1,1,0,1,0]+[0,0,0,0,0,1,0,1,0,1,1,0,0,1,1,1,0,0,0,0]+[0]*8, True, 1, [packet_time_est_tag])
self.blocks_throttle_0 = blocks.throttle(gr.sizeof_float*1, samp_rate,True)
self.blocks_repeat_0 = blocks.repeat(gr.sizeof_float*1, 10*5)
self.blocks_null_source_1 = blocks.null_source(gr.sizeof_float*1)
self.blocks_multiply_const_vxx_1 = blocks.multiply_const_vff((signal_strength * 0.001, ))
self.blocks_multiply_const_vxx_0 = blocks.multiply_const_vff((1000.0/signal_strength, ))
self.blocks_float_to_complex_0 = blocks.float_to_complex(1)
self.blocks_float_to_char_0 = blocks.float_to_char(1, 1)
self.blocks_file_source_0 = blocks.file_source(gr.sizeof_float*1, '/home/user/research/smart_meter_reset/gm_platform/fw/raw_freq.bin', True)
self.blocks_file_source_0.set_begin_tag(pmt.PMT_NIL)
self.blocks_file_sink_0 = blocks.file_sink(gr.sizeof_float*1, ber_file, False)
self.blocks_file_sink_0.set_unbuffered(False)
self.blocks_delay_0 = blocks.delay(gr.sizeof_float*1, ber_delay)
self.blocks_complex_to_real_0 = blocks.complex_to_real(1)
self.blocks_add_xx_0 = blocks.add_vff(1)
self.blocks_add_const_vxx_1 = blocks.add_const_vff((-signal_strength*0.001/2.0, ))
self.blocks_add_const_vxx_0 = blocks.add_const_vff((-50, ))
##################################################
# Connections
##################################################
self.connect((self.blocks_add_const_vxx_0, 0), (self.blocks_add_xx_0, 0))
self.connect((self.blocks_add_const_vxx_1, 0), (self.blocks_add_xx_0, 1))
self.connect((self.blocks_add_xx_0, 0), (self.blocks_float_to_complex_0, 0))
self.connect((self.blocks_complex_to_real_0, 0), (self.blocks_multiply_const_vxx_0, 0))
self.connect((self.blocks_delay_0, 0), (self.blocks_float_to_char_0, 0))
self.connect((self.blocks_file_source_0, 0), (self.blocks_throttle_0, 0))
self.connect((self.blocks_float_to_char_0, 0), (self.fec_ber_bf_0, 1))
self.connect((self.blocks_float_to_complex_0, 0), (self.high_pass_filter_0, 0))
self.connect((self.blocks_multiply_const_vxx_0, 0), (self.digital_clock_recovery_mm_xx_0, 0))
self.connect((self.blocks_multiply_const_vxx_1, 0), (self.blocks_add_const_vxx_1, 0))
self.connect((self.blocks_null_source_1, 0), (self.blocks_float_to_complex_0, 1))
self.connect((self.blocks_repeat_0, 0), (self.blocks_multiply_const_vxx_1, 0))
self.connect((self.blocks_throttle_0, 0), (self.blocks_add_const_vxx_0, 0))
self.connect((self.blocks_vector_source_x_0_0_1_0, 0), (self.blocks_delay_0, 0))
self.connect((self.blocks_vector_source_x_0_0_1_0, 0), (self.blocks_repeat_0, 0))
self.connect((self.digital_binary_slicer_fb_0, 0), (self.fec_ber_bf_0, 0))
self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.digital_binary_slicer_fb_0, 0))
self.connect((self.fec_ber_bf_0, 0), (self.blocks_file_sink_0, 0))
self.connect((self.high_pass_filter_0, 0), (self.low_pass_filter_0, 0))
self.connect((self.low_pass_filter_0, 0), (self.blocks_complex_to_real_0, 0))
def get_ber_file(self):
return self.ber_file
def set_ber_file(self, ber_file):
self.ber_file = ber_file
self.blocks_file_sink_0.open(self.ber_file)
def get_signal_strength(self):
return self.signal_strength
def set_signal_strength(self, signal_strength):
self.signal_strength = signal_strength
self.blocks_multiply_const_vxx_1.set_k((self.signal_strength * 0.001, ))
self.blocks_multiply_const_vxx_0.set_k((1000.0/self.signal_strength, ))
self.blocks_add_const_vxx_1.set_k((-self.signal_strength*0.001/2.0, ))
def get_sim_mul(self):
return self.sim_mul
def set_sim_mul(self, sim_mul):
self.sim_mul = sim_mul
self.set_samp_rate(self.actual_sampling_rate*self.sim_mul)
self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.samp_rate, 0.1 * self.sim_mul, 0.05 * self.sim_mul, firdes.WIN_HAMMING, 6.76))
self.high_pass_filter_0.set_taps(firdes.high_pass(1, self.samp_rate, self.sim_mul/200, self.sim_mul/800, firdes.WIN_HAMMING, 6.76))
def get_actual_sampling_rate(self):
return self.actual_sampling_rate
def set_actual_sampling_rate(self, actual_sampling_rate):
self.actual_sampling_rate = actual_sampling_rate
self.set_samp_rate(self.actual_sampling_rate*self.sim_mul)
def get_sync_tag(self):
return self.sync_tag
def set_sync_tag(self, sync_tag):
self.sync_tag = sync_tag
def get_samp_rate(self):
return self.samp_rate
def set_samp_rate(self, samp_rate):
self.samp_rate = samp_rate
self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.samp_rate, 0.1 * self.sim_mul, 0.05 * self.sim_mul, firdes.WIN_HAMMING, 6.76))
self.high_pass_filter_0.set_taps(firdes.high_pass(1, self.samp_rate, self.sim_mul/200, self.sim_mul/800, firdes.WIN_HAMMING, 6.76))
self.blocks_throttle_0.set_sample_rate(self.samp_rate)
def get_pi(self):
return self.pi
def set_pi(self, pi):
self.pi = pi
def get_packet_time_est_tag(self):
return self.packet_time_est_tag
def set_packet_time_est_tag(self, packet_time_est_tag):
self.packet_time_est_tag = packet_time_est_tag
self.blocks_vector_source_x_0_0_1_0.set_data([1,0]*(4*12)+[1,1,0,1,0,1,0,1]*12+[1,0,1,1,1,1,1,0,0,1]+[1,1,1,1,0,1,1,0,0,1]+[1,0,1,1,1,1,1,0,0,1]+[0,1,1,1,0,1,1,0,1,0]+[0,0,0,0,0,1,0,1,0,1,1,0,0,1,1,1,0,0,0,0]+[0]*8, [self.packet_time_est_tag])
def get_ber_delay(self):
return self.ber_delay
def set_ber_delay(self, ber_delay):
self.ber_delay = ber_delay
self.blocks_delay_0.set_dly(self.ber_delay)
def argument_parser():
parser = OptionParser(usage="%prog: [options]", option_class=eng_option)
parser.add_option(
"", "--ber-file", dest="ber_file", type="string", default='0',
help="Set BER data output file [default=%default]")
parser.add_option(
"", "--signal-strength", dest="signal_strength", type="eng_float", default=eng_notation.num_to_str(50),
help="Set signal strength in mHz [default=%default]")
return parser
def main(top_block_cls=dec_proto_am_dc_ber_top, options=None):
if options is None:
options, _ = argument_parser().parse_args()
tb = top_block_cls(ber_file=options.ber_file, signal_strength=options.signal_strength)
tb.start()
try:
raw_input('Press Enter to quit: ')
except EOFError:
pass
tb.stop()
tb.wait()
if __name__ == '__main__':
main()

183
dec_proto_fm_ber_top.py Executable file
View file

@ -0,0 +1,183 @@
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
##################################################
# GNU Radio Python Flow Graph
# Title: Dec Proto Fm Ber Top
# GNU Radio version: 3.7.13.5
##################################################
from gnuradio import analog
from gnuradio import blocks
from gnuradio import digital
from gnuradio import eng_notation
from gnuradio import fec
from gnuradio import filter
from gnuradio import gr
from gnuradio.eng_option import eng_option
from gnuradio.filter import firdes
from optparse import OptionParser
import math
import pmt
class dec_proto_fm_ber_top(gr.top_block):
def __init__(self, ber_file='0', signal_strength=1):
gr.top_block.__init__(self, "Dec Proto Fm Ber Top")
##################################################
# Parameters
##################################################
self.ber_file = ber_file
self.signal_strength = signal_strength
##################################################
# Variables
##################################################
self.sim_mul = sim_mul = 1e4
self.actual_sampling_rate = actual_sampling_rate = 10
self.sync_tag = sync_tag = gr.tag_utils.python_to_tag((0, pmt.intern("sync"), pmt.from_double(0.0), pmt.intern("correlate_access_code")))
self.samp_rate = samp_rate = actual_sampling_rate*sim_mul
self.pi = pi = 3.141592653589793
self.packet_time_est_tag = packet_time_est_tag = gr.tag_utils.python_to_tag((0, pmt.intern("start"), pmt.from_double(0.0), pmt.intern("packet_vector_source")))
##################################################
# Blocks
##################################################
self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass(
1, samp_rate, 0.1 * sim_mul, 0.05 * sim_mul, firdes.WIN_HAMMING, 6.76))
self.fec_ber_bf_0 = fec.ber_bf(False, 0, -7.0)
self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(50, 0.001, 0, 0.01, 0.01)
self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb()
self.blocks_vector_source_x_0_0_1_0 = blocks.vector_source_f([1,0]*(4*12)+[1,1,0,1,0,1,0,1]*12+[1,0,1,1,1,1,1,0,0,1]+[1,1,1,1,0,1,1,0,0,1]+[1,0,1,1,1,1,1,0,0,1]+[0,1,1,1,0,1,1,0,1,0]+[0,0,0,0,0,1,0,1,0,1,1,0,0,1,1,1,0,0,0,0]+[0]*128, True, 1, [packet_time_est_tag])
self.blocks_vco_f_0 = blocks.vco_f(samp_rate, sim_mul*2*pi, signal_strength*1e-3)
self.blocks_throttle_0 = blocks.throttle(gr.sizeof_float*1, samp_rate,True)
self.blocks_repeat_0 = blocks.repeat(gr.sizeof_float*1, 10*5)
self.blocks_null_source_1 = blocks.null_source(gr.sizeof_float*1)
self.blocks_multiply_xx_0 = blocks.multiply_vcc(1)
self.blocks_multiply_const_vxx_1 = blocks.multiply_const_vff((0.2, ))
self.blocks_float_to_complex_0 = blocks.float_to_complex(1)
self.blocks_float_to_char_0 = blocks.float_to_char(1, 1)
self.blocks_file_source_0 = blocks.file_source(gr.sizeof_float*1, '/home/user/research/smart_meter_reset/gm_platform/fw/raw_freq.bin', True)
self.blocks_file_source_0.set_begin_tag(pmt.PMT_NIL)
self.blocks_file_sink_0 = blocks.file_sink(gr.sizeof_float*1, ber_file, False)
self.blocks_file_sink_0.set_unbuffered(False)
self.blocks_delay_0 = blocks.delay(gr.sizeof_float*1, 5)
self.blocks_add_xx_0 = blocks.add_vff(1)
self.blocks_add_const_vxx_1 = blocks.add_const_vff((1.0, ))
self.blocks_add_const_vxx_0 = blocks.add_const_vff((-50, ))
self.analog_sig_source_x_0 = analog.sig_source_c(samp_rate, analog.GR_COS_WAVE, -1.1 * sim_mul, 1, 0)
self.analog_quadrature_demod_cf_0 = analog.quadrature_demod_cf(8)
##################################################
# Connections
##################################################
self.connect((self.analog_quadrature_demod_cf_0, 0), (self.digital_clock_recovery_mm_xx_0, 0))
self.connect((self.analog_sig_source_x_0, 0), (self.blocks_multiply_xx_0, 1))
self.connect((self.blocks_add_const_vxx_0, 0), (self.blocks_add_xx_0, 0))
self.connect((self.blocks_add_const_vxx_1, 0), (self.blocks_vco_f_0, 0))
self.connect((self.blocks_add_xx_0, 0), (self.blocks_float_to_complex_0, 0))
self.connect((self.blocks_delay_0, 0), (self.blocks_float_to_char_0, 0))
self.connect((self.blocks_file_source_0, 0), (self.blocks_throttle_0, 0))
self.connect((self.blocks_float_to_char_0, 0), (self.fec_ber_bf_0, 1))
self.connect((self.blocks_float_to_complex_0, 0), (self.blocks_multiply_xx_0, 0))
self.connect((self.blocks_multiply_const_vxx_1, 0), (self.blocks_add_const_vxx_1, 0))
self.connect((self.blocks_multiply_xx_0, 0), (self.low_pass_filter_0, 0))
self.connect((self.blocks_null_source_1, 0), (self.blocks_float_to_complex_0, 1))
self.connect((self.blocks_repeat_0, 0), (self.blocks_multiply_const_vxx_1, 0))
self.connect((self.blocks_throttle_0, 0), (self.blocks_add_const_vxx_0, 0))
self.connect((self.blocks_vco_f_0, 0), (self.blocks_add_xx_0, 1))
self.connect((self.blocks_vector_source_x_0_0_1_0, 0), (self.blocks_delay_0, 0))
self.connect((self.blocks_vector_source_x_0_0_1_0, 0), (self.blocks_repeat_0, 0))
self.connect((self.digital_binary_slicer_fb_0, 0), (self.fec_ber_bf_0, 0))
self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.digital_binary_slicer_fb_0, 0))
self.connect((self.fec_ber_bf_0, 0), (self.blocks_file_sink_0, 0))
self.connect((self.low_pass_filter_0, 0), (self.analog_quadrature_demod_cf_0, 0))
def get_ber_file(self):
return self.ber_file
def set_ber_file(self, ber_file):
self.ber_file = ber_file
self.blocks_file_sink_0.open(self.ber_file)
def get_signal_strength(self):
return self.signal_strength
def set_signal_strength(self, signal_strength):
self.signal_strength = signal_strength
def get_sim_mul(self):
return self.sim_mul
def set_sim_mul(self, sim_mul):
self.sim_mul = sim_mul
self.set_samp_rate(self.actual_sampling_rate*self.sim_mul)
self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.samp_rate, 0.1 * self.sim_mul, 0.05 * self.sim_mul, firdes.WIN_HAMMING, 6.76))
self.analog_sig_source_x_0.set_frequency(-1.1 * self.sim_mul)
def get_actual_sampling_rate(self):
return self.actual_sampling_rate
def set_actual_sampling_rate(self, actual_sampling_rate):
self.actual_sampling_rate = actual_sampling_rate
self.set_samp_rate(self.actual_sampling_rate*self.sim_mul)
def get_sync_tag(self):
return self.sync_tag
def set_sync_tag(self, sync_tag):
self.sync_tag = sync_tag
def get_samp_rate(self):
return self.samp_rate
def set_samp_rate(self, samp_rate):
self.samp_rate = samp_rate
self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.samp_rate, 0.1 * self.sim_mul, 0.05 * self.sim_mul, firdes.WIN_HAMMING, 6.76))
self.blocks_throttle_0.set_sample_rate(self.samp_rate)
self.analog_sig_source_x_0.set_sampling_freq(self.samp_rate)
def get_pi(self):
return self.pi
def set_pi(self, pi):
self.pi = pi
def get_packet_time_est_tag(self):
return self.packet_time_est_tag
def set_packet_time_est_tag(self, packet_time_est_tag):
self.packet_time_est_tag = packet_time_est_tag
self.blocks_vector_source_x_0_0_1_0.set_data([1,0]*(4*12)+[1,1,0,1,0,1,0,1]*12+[1,0,1,1,1,1,1,0,0,1]+[1,1,1,1,0,1,1,0,0,1]+[1,0,1,1,1,1,1,0,0,1]+[0,1,1,1,0,1,1,0,1,0]+[0,0,0,0,0,1,0,1,0,1,1,0,0,1,1,1,0,0,0,0]+[0]*128, [self.packet_time_est_tag])
def argument_parser():
parser = OptionParser(usage="%prog: [options]", option_class=eng_option)
parser.add_option(
"", "--ber-file", dest="ber_file", type="string", default='0',
help="Set BER data output file [default=%default]")
parser.add_option(
"", "--signal-strength", dest="signal_strength", type="eng_float", default=eng_notation.num_to_str(1),
help="Set signal strength in mHz [default=%default]")
return parser
def main(top_block_cls=dec_proto_fm_ber_top, options=None):
if options is None:
options, _ = argument_parser().parse_args()
tb = top_block_cls(ber_file=options.ber_file, signal_strength=options.signal_strength)
tb.start()
try:
raw_input('Press Enter to quit: ')
except EOFError:
pass
tb.stop()
tb.wait()
if __name__ == '__main__':
main()

3142
decoder_prototype.grc Normal file

File diff suppressed because it is too large Load diff

3760
decoder_prototype10.grc Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

3817
decoder_prototype11.grc Normal file

File diff suppressed because it is too large Load diff

5658
decoder_prototype2.grc Normal file

File diff suppressed because it is too large Load diff

2286
decoder_prototype3.grc Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

3794
decoder_prototype4.grc Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

5434
decoder_prototype5.grc Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

5664
decoder_prototype6.grc Normal file

File diff suppressed because it is too large Load diff

2371
decoder_prototype7.grc Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

3489
decoder_prototype8.grc Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

3558
decoder_prototype9.grc Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

73
sweep_gr_sims.py Normal file
View file

@ -0,0 +1,73 @@
#!/usr/bin/env python3
import subprocess
import time
import struct
import math
import statistics
import tempfile
import itertools
from os import path
import tqdm
SIMS = [ 'dec_proto_am_ber_top.py',
'dec_proto_am_dc_ber_top.py',
'dec_proto_fm_ber_top.py',
]
E12_SERIES = [1.0, 1.2, 1.5, 1.8, 2.2, 2.7, 3.3, 3.9, 4.7, 5.6, 6.8, 8.2]
AMPLITUDES_MILLIHERTZ = [ x*y for y in [1, 10, 100] for x in E12_SERIES ]
SIMULATION_DURATION = 30.0 # seconds realtime
MAX_CONCURRENT_PROCESSES = 8
with tempfile.TemporaryDirectory() as tmpdir:
jobs = list(enumerate(itertools.product(SIMS, AMPLITUDES_MILLIHERTZ)))
print(f'Will launch {len(jobs)} simulation jobs in {math.ceil(len(jobs)/MAX_CONCURRENT_PROCESSES):.0f} batches of {MAX_CONCURRENT_PROCESSES}')
def start_processes(jobs):
for i, (sim, ampl_mhz) in jobs:
berfile = path.join(tmpdir, f'berfile_{i}')
proc = subprocess.Popen(['/usr/bin/python2', sim,
'--signal-strength', str(ampl_mhz),
'--ber-file', berfile],
stdin=subprocess.PIPE, stdout=subprocess.DEVNULL)
yield proc, sim, ampl_mhz, berfile
results = { sim: ([], [], []) for sim in SIMS }
for n, i in enumerate(range(0, len(jobs), MAX_CONCURRENT_PROCESSES)):
batch = jobs[i:][:MAX_CONCURRENT_PROCESSES]
print(f'Starting batch {n}... ', end='')
processes = list(start_processes(batch))
print('done.')
print('Waiting for simulation:')
for _ in tqdm.trange(1000):
time.sleep(SIMULATION_DURATION/1000)
print('Terminating processes...', end='')
for proc, *_ in processes:
proc.communicate(b'\n', timeout=10)
for proc, *_ in processes:
proc.wait(5)
print('done.')
print('Processing simulation results')
for _proc, sim, ampl_mhz, berfile in processes:
with open(berfile, 'rb') as f:
data = f.read()
floats = struct.unpack(f'{len(data)//4}f', data)
ber = statistics.mean(floats[-256:])
stdev = statistics.stdev(floats[-256:])
amplitudes, bers, stdevs = results[sim]
amplitudes.append(ampl_mhz)
bers.append(ber)
stdevs.append(stdev)
print(results)