Exemplo n.º 1
0
  def add_mobile_station(self,station_id):
    """
    Adds new receiver mobile station. Station ID must be unique. Initializes
    BER reference source.
    """

    # Initialize
    id_src = self._control._id_source
    dmux = self._data_multiplexer
    port = self._data_multiplexer_nextport
    self._data_multiplexer_nextport += 1

    # Setup
    ctrl_port = self._control.add_mobile_station(station_id)
    options = self._options
    if options.imgxfer:
      ref_src = ofdm.imgtransfer_src( options.img )
    else:
      ref_src = ber_reference_source(self._options)
    
    if(options.coding):
        ## Encoder
        encoder = self._encoder = ofdm.encoder_bb(fo,0)
        unpack = self._unpack = blocks.unpack_k_bits_bb(2)
        
        ## Puncturing
        if not options.nopunct:
            puncturing = self._puncturing = puncture_bb(options.subcarriers)
            #sah = gr.sample_and_hold_bb()
            #sah_trigger = blocks.vector_source_b([1,0],True)
            #decim_sah=gr.keep_one_in_n(gr.sizeof_char,2)
            self.connect(self._bitmap_trigger_puncturing,(puncturing,2))
            frametrigger_bitmap_filter = blocks.vector_source_b([1,0],True)
            bitmap_filter = self._puncturing_bitmap_src_filter = skip(gr.sizeof_char*options.subcarriers,2)# skip_known_symbols(frame_length,subcarriers)
            bitmap_filter.skip_call(0)
            #self.connect(self._bitmap_src_puncturing,bitmap_filter,(puncturing,1))
            self.connect(self._map_src,bitmap_filter,(puncturing,1))
            self.connect(frametrigger_bitmap_filter,(bitmap_filter,1))
            #bmt = gr.char_to_float()
            #self.connect(bitmap_filter,blocks.vector_to_stream(gr.sizeof_char,options.subcarriers), bmt)
            #log_to_file(self, bmt, "data/bitmap_filter_tx.float")
            
        self.connect((self._control,ctrl_port),ref_src,encoder,unpack)
        if not options.nopunct:
            self.connect(unpack,puncturing,(dmux,port))
            #self.connect(sah_trigger, (sah,1))
        else:
            self.connect(unpack,(dmux,port))
    else:
        self.connect((self._control,ctrl_port),ref_src,(dmux,port))
    
    if options.log and options.coding:
        log_to_file(self, encoder, "data/encoder_out.char")
        log_to_file(self, ref_src, "data/reference_data_src.char")
        log_to_file(self, unpack, "data/encoder_unpacked_out.char")
        if not options.nopunct:
            log_to_file(self, puncturing, "data/puncturing_out.char")
  def __init__( self, vlen, framelength, no_preambles = 1 ):
    gr.hier_block2.__init__( self,
          "ofdm_data_block_filter",
          gr.io_signature( 1, 1, gr.sizeof_gr_complex * vlen ),
          gr.io_signature( 1, 1, gr.sizeof_gr_complex * vlen ) )

    datablock_filter = ofdm.skip( gr.sizeof_gr_complex * vlen,
                                  framelength )
    for i in range( no_preambles ):
      datablock_filter.skip( i )

    frame_trigger = ofdm_perfect_frame_trigger( framelength )

    self.connect( self, datablock_filter, self )
    self.connect( frame_trigger, ( datablock_filter, 1 ) )

    self.frame_trigger = frame_trigger
Exemplo n.º 3
0
  def setup_snr_measurement(self):
    """
    Perform SNR measurement.
    It uses the data reference from the BER measurement. I.e. if that is not
    setup, it will be setup. Only data subcarriers that are assigned to the
    station are considered in the measurement. Note that there is no sink
    prepared. You need to setup a sink, e.g. with one or more invocation
    of a "publish.."-function.
    SNR output is in dB.
    """
    if not self.measuring_ber():
      self.setup_ber_measurement()
      print "Warning: Setup BER Measurement forced"

    if self.measuring_snr():
      return

    config = station_configuration()

    vlen = config.subcarriers
    frame_length = config.frame_length
    L = config.periodic_parts
    
    snr_est_filt = skip(gr.sizeof_gr_complex*vlen,frame_length/2)
    skipping_symbols = [0] + range(config.training_data.fbmc_no_preambles/2,frame_length/2)
    for x in skipping_symbols:
        snr_est_filt.skip_call(x)

    #snr_est_filt = skip(gr.sizeof_gr_complex*vlen,frame_length)
    #for x in range(1,frame_length):
      #snr_est_filt.skip_call(x)

    ## NOTE HACK!! first preamble is not equalized

    self.connect(self.symbol_output,snr_est_filt)
    self.connect(self.frame_trigger,(snr_est_filt,1))

#    snrm = self._snr_measurement = milans_snr_estimator( vlen, vlen, L )
#
#    self.connect(snr_est_filt,snrm)
#
#    if self._options.log:
#          log_to_file(self, self._snr_measurement, "data/milan_snr.float")

    #Addition for SINR estimation
    if self._options.sinr_est:
        snr_est_filt_2 = skip(gr.sizeof_gr_complex*vlen,frame_length)
        for x in range(frame_length):
          if x != config.training_data.channel_estimation_pilot[0]:
            snr_est_filt_2.skip_call(x)

        self.connect(self.symbol_output,snr_est_filt_2)
        self.connect(self.frame_trigger,(snr_est_filt_2,1))

        sinrm = self._sinr_measurement = milans_sinr_sc_estimator2( vlen, vlen, L )

        self.connect(snr_est_filt,sinrm)
        self.connect(snr_est_filt_2,(sinrm,1))
        if self._options.log:
            log_to_file(self, (self._sinr_measurement,0), "data/milan_sinr_sc.float")
            log_to_file(self, (self._sinr_measurement,1), "data/milan_snr.float")

    else:
        #snrm = self._snr_measurement = milans_snr_estimator( vlen, vlen, L )
        snr_estim = fbmc_snr_estimator( vlen, config.training_data.fbmc_no_preambles/2 -1 )
        scsnrdb = filter.single_pole_iir_filter_ff(0.1)
        snrm = self._snr_measurement = blocks.nlog10_ff(10,1,0)
        #self.connect(self.snr_est_preamble,scsnrdb,snrm)
        #terminate_stream(self,self.snr_est_preamble)
        #self.connect(self.snr_est_preamble,snr_estim,scsnrdb,snrm)
        #self.connect((snr_estim,1),blocks.null_sink(gr.sizeof_float))
        #log_to_file(self, snrm, "data/snrm.float")
        
        #log_to_file(self, snrm, "data/snrm.float")
        collect_preambles = blocks.stream_to_vector(gr.sizeof_gr_complex*vlen, config.training_data.fbmc_no_preambles/2 -1)
        self.connect(snr_est_filt, collect_preambles)
        self.connect(collect_preambles,snr_estim,scsnrdb,snrm)
        self.connect((snr_estim,1),blocks.null_sink(gr.sizeof_float))
Exemplo n.º 4
0
  def __init__(self, options):
    gr.hier_block2.__init__(self, "fbmc_receive_path",
        gr.io_signature(1,1,gr.sizeof_gr_complex),
        gr.io_signature(0,0,0))

    print "This is  FBMC receive path 1x1"

    common_options.defaults(options)

    config = self.config = station_configuration()

    config.data_subcarriers     = dsubc = options.subcarriers
    config.cp_length            = 0
    config.frame_data_blocks    = options.data_blocks
    config._verbose             = options.verbose #TODO: update
    config.fft_length           = options.fft_length
    config.dc_null             = options.dc_null
    config.training_data        = default_block_header(dsubc,
                                          config.fft_length,config.dc_null,options)
    config.coding              = options.coding
    config.ber_window           = options.ber_window

    config.periodic_parts       = 8

    config.frame_id_blocks      = 1 # FIXME

    self._options               = copy.copy(options) #FIXME: do we need this?
    
    config.fbmc                 = options.fbmc

    

    config.block_length = config.fft_length + config.cp_length
    config.frame_data_part = config.frame_data_blocks + config.frame_id_blocks
    config.frame_length = config.training_data.fbmc_no_preambles + 2*config.frame_data_part 
    
    config.postpro_frame_length = config.frame_data_part + \
                          config.training_data.no_pilotsyms
    config.subcarriers = dsubc + \
                         config.training_data.pilot_subcarriers
    config.virtual_subcarriers = config.fft_length - config.subcarriers - config.dc_null

    total_subc = config.subcarriers
    


    # check some bounds
    if config.fft_length < config.subcarriers:
      raise SystemError, "Subcarrier number must be less than FFT length"
    if config.fft_length < config.cp_length:
      raise SystemError, "Cyclic prefix length must be less than FFT length"



    #self.input =  gr.kludge_copy(gr.sizeof_gr_complex)
    #self.connect( self, self.input )
    self.input = self
    self.ideal = options.ideal
    self.ideal2 = options.ideal2


    ## Inner receiver

    ## Timing & Frequency Synchronization
    ## Channel estimation + Equalization
    ## Phase Tracking for sampling clock frequency offset correction
    inner_receiver = self.inner_receiver = fbmc_inner_receiver( options, options.log )
    self.connect( self.input, inner_receiver )
    ofdm_blocks = ( inner_receiver, 2 )
    frame_start = ( inner_receiver, 1 )
    disp_ctf = ( inner_receiver, 0 )
    #self.snr_est_preamble = ( inner_receiver, 3 )
    #terminate_stream(self,snr_est_preamble)
    disp_cfo =  ( inner_receiver, 3 )
    
    if self.ideal is False and self.ideal2 is False:
        self.zmq_probe_freqoff = zeromq.pub_sink(gr.sizeof_float, 1, "tcp://*:5557")
        self.connect(disp_cfo, self.zmq_probe_freqoff)
    else:
        self.connect(disp_cfo, blocks.null_sink(gr.sizeof_float))




    # for ID decoder
    used_id_bits = config.used_id_bits = 8 #TODO: constant in source code!
    rep_id_bits = config.rep_id_bits = dsubc/used_id_bits #BPSK
    if options.log:
      print "rep_id_bits %d" % (rep_id_bits)
    if dsubc % used_id_bits <> 0:
      raise SystemError,"Data subcarriers need to be multiple of 10"

    ## Workaround to avoid periodic structure
    seed(1)
    whitener_pn = [randint(0,1) for i in range(used_id_bits*rep_id_bits)]





    ## NOTE!!! BIG HACK!!!
    ## first preamble ain't equalized ....
    ## for Milan's SNR estimator






    ## Outer Receiver

    ## Make new inner receiver compatible with old outer receiver
    ## FIXME: renew outer receiver

    self.ctf = disp_ctf

    #frame_sampler = ofdm_frame_sampler(options)
    frame_sampler = fbmc_frame_sampler(options)

    self.connect( ofdm_blocks, frame_sampler)
    self.connect( frame_start, (frame_sampler,1) )


#
#    ft = [0] * config.frame_length
#    ft[0] = 1
#
#    # The next block ensures that only complete frames find their way into
#    # the old outer receiver. The dynamic frame start trigger is hence
#    # replaced with a static one, fixed to the frame length.
#
#    frame_sampler = ofdm.vector_sampler( gr.sizeof_gr_complex * total_subc,
#                                              config.frame_length )
#    self.symbol_output = blocks.vector_to_stream( gr.sizeof_gr_complex * total_subc,
#                                              config.frame_length )
#    delayed_frame_start = blocks.delay( gr.sizeof_char, config.frame_length - 1 )
#    damn_static_frame_trigger = blocks.vector_source_b( ft, True )
#
#    if options.enable_erasure_decision:
#      frame_gate = vector_sampler(
#        gr.sizeof_gr_complex * total_subc * config.frame_length, 1 )
#      self.connect( ofdm_blocks, frame_sampler, frame_gate,
#                    self.symbol_output )
#    else:
#      self.connect( ofdm_blocks, frame_sampler, self.symbol_output )
#
#    self.connect( frame_start, delayed_frame_start, ( frame_sampler, 1 ) )

    if options.enable_erasure_decision:
      frame_gate = frame_sampler.frame_gate

    self.symbol_output = frame_sampler

    orig_frame_start = frame_start
    frame_start = (frame_sampler,1)
    self.frame_trigger = frame_start
    #terminate_stream(self, self.frame_trigger)








    ## Pilot block filter
    pb_filt = self._pilot_block_filter = fbmc_pilot_block_filter()
    self.connect(self.symbol_output,pb_filt)
    self.connect(self.frame_trigger,(pb_filt,1))

    self.frame_data_trigger = (pb_filt,1)
    
    #self.symbol_output = pb_filt
    

    #if options.log:
      #log_to_file(self, pb_filt, "data/pb_filt_out.compl")


    if config.fbmc:
        pda_in = pb_filt

    else:
        ## Pilot subcarrier filter
        ps_filt = self._pilot_subcarrier_filter = pilot_subcarrier_filter()
        self.connect(self.symbol_output,ps_filt)

        if options.log:
            log_to_file(self, ps_filt, "data/ps_filt_out.compl")
            
        pda_in = ps_filt

    


    ## Workaround to avoid periodic structure
    # for ID decoder
    seed(1)
    whitener_pn = [randint(0,1) for i in range(used_id_bits*rep_id_bits)]

    

    if not options.enable_erasure_decision:

      ## ID Block Filter
      # Filter ID block, skip data blocks
      id_bfilt = self._id_block_filter = vector_sampler(
            gr.sizeof_gr_complex * dsubc, 1 )
      if not config.frame_id_blocks == 1:
        raise SystemExit, "# ID Blocks > 1 not supported"

      self.connect(   pda_in     ,   id_bfilt      )
      self.connect( self.frame_data_trigger, ( id_bfilt, 1 ) ) # trigger

      #log_to_file( self, id_bfilt, "data/id_bfilt.compl" )

      ## ID Demapper and Decoder, soft decision
      self.id_dec = self._id_decoder = ofdm.coded_bpsk_soft_decoder( dsubc,
          used_id_bits, whitener_pn )
      self.connect( id_bfilt, self.id_dec )
      

      print "Using coded BPSK soft decoder for ID detection"


    else: # options.enable_erasure_decision:

      id_bfilt = self._id_block_filter = vector_sampler(
        gr.sizeof_gr_complex * total_subc, config.frame_id_blocks )

      id_bfilt_trig_delay = 0
      for x in range( config.frame_length ):
        if x in config.training_data.pilotsym_pos:
          id_bfilt_trig_delay += 1
        else:
          break
      print "Position of ID block within complete frame: %d" %(id_bfilt_trig_delay)

      assert( id_bfilt_trig_delay > 0 ) # else not supported

      id_bfilt_trig = blocks.delay( gr.sizeof_char, id_bfilt_trig_delay )

      self.connect( ofdm_blocks, id_bfilt )
      self.connect( orig_frame_start, id_bfilt_trig, ( id_bfilt, 1 ) )

      self.id_dec = self._id_decoder = ofdm.coded_bpsk_soft_decoder( total_subc,
          used_id_bits, whitener_pn, config.training_data.shifted_pilot_tones )
      self.connect( id_bfilt, self.id_dec )

      print "Using coded BPSK soft decoder for ID detection"

      # The threshold block either returns 1.0 if the llr-value from the
      # id decoder is below the threshold, else 0.0. Hence we convert this
      # into chars, 0 and 1, and use it as trigger for the sampler.

      min_llr = ( self.id_dec, 1 )
      erasure_threshold = gr.threshold_ff( 10.0, 10.0, 0 ) # FIXME is it the optimal threshold?
      erasure_dec = gr.float_to_char()
      id_gate = vector_sampler( gr.sizeof_short, 1 )
      ctf_gate = vector_sampler( gr.sizeof_float * total_subc, 1 )


      self.connect( self.id_dec ,       id_gate )
      self.connect( self.ctf,      ctf_gate )

      self.connect( min_llr,       erasure_threshold,  erasure_dec )
      self.connect( erasure_dec, ( frame_gate, 1 ) )
      self.connect( erasure_dec, ( id_gate,    1 ) )
      self.connect( erasure_dec, ( ctf_gate,   1 ) )

      self.id_dec = self._id_decoder = id_gate
      self.ctf = ctf_gate



      print "Erasure decision for IDs is enabled"




    if options.log:
      id_dec_f = gr.short_to_float()
      self.connect(self.id_dec,id_dec_f)
      log_to_file(self, id_dec_f, "data/id_dec_out.float")


    if options.log:
      log_to_file(self, id_bfilt, "data/id_blockfilter_out.compl")


    # TODO: refactor names




    if options.log:
      map_src_f = gr.char_to_float(dsubc)
      self.connect(map_src,map_src_f)
      log_to_file(self, map_src_f, "data/map_src_out.float")

    ## Allocation Control
    if options.static_allocation: #DEBUG
        
        if options.coding:
            mode = 1 # Coding mode 1-9
            bitspermode = [0.5,1,1.5,2,3,4,4.5,5,6] # Information bits per mode
            bitcount_vec = [(int)(config.data_subcarriers*config.frame_data_blocks*bitspermode[mode-1])]
            bitloading = mode
        else:
            bitloading = 1
            bitcount_vec = [config.data_subcarriers*config.frame_data_blocks*bitloading]
        #bitcount_vec = [config.data_subcarriers*config.frame_data_blocks]
        self.bitcount_src = blocks.vector_source_i(bitcount_vec,True,1)
        # 0s for ID block, then data
        #bitloading_vec = [0]*dsubc+[0]*(dsubc/2)+[2]*(dsubc/2)
        bitloading_vec = [0]*dsubc+[bitloading]*dsubc
        bitloading_src = blocks.vector_source_b(bitloading_vec,True,dsubc)
        power_vec = [1]*config.data_subcarriers
        power_src = blocks.vector_source_f(power_vec,True,dsubc)
    else:
        self.allocation_buffer = ofdm.allocation_buffer(config.data_subcarriers, config.frame_data_blocks, "tcp://"+options.tx_hostname+":3333",config.coding)
        self.bitcount_src = (self.allocation_buffer,0)
        bitloading_src = (self.allocation_buffer,1)
        power_src = (self.allocation_buffer,2)
        self.connect(self.id_dec, self.allocation_buffer)
        if options.benchmarking:
            self.allocation_buffer.set_allocation([4]*config.data_subcarriers,[1]*config.data_subcarriers)

    if options.log:
        log_to_file(self, self.bitcount_src, "data/bitcount_src_rx.int")
        log_to_file(self, bitloading_src, "data/bitloading_src_rx.char")
        log_to_file(self, power_src, "data/power_src_rx.cmplx")
        log_to_file(self, self.id_dec, "data/id_dec_rx.short")

    ## Power Deallocator
    pda = self._power_deallocator = multiply_frame_fc(config.frame_data_part, dsubc)
    self.connect(pda_in,(pda,0))
    self.connect(power_src,(pda,1))

    ## Demodulator
#    if 0:
#          ac_vector = [0.0+0.0j]*208
#          ac_vector[0] = (2*10**(-0.452))
#          ac_vector[3] = (10**(-0.651))
#          ac_vector[7] = (10**(-1.151))
#          csi_vector_inv=abs(numpy.fft.fft(numpy.sqrt(ac_vector)))**2
#          dm_csi = numpy.fft.fftshift(csi_vector_inv) # TODO

    dm_csi = [1]*dsubc # TODO
    dm_csi = blocks.vector_source_f(dm_csi,True)
    ## Depuncturer
    dp_trig = [0]*(config.frame_data_blocks/2)
    dp_trig[0] = 1
    dp_trig = blocks.vector_source_b(dp_trig,True) # TODO



    if(options.coding):
        fo=ofdm.fsm(1,2,[91,121])
        if options.interleave:
            int_object=trellis.interleaver(2000,666)
            deinterlv = trellis.permutation(int_object.K(),int_object.DEINTER(),1,gr.sizeof_float)
        
        demod = self._data_demodulator = generic_softdemapper_vcf(dsubc, config.frame_data_part, config.coding)
        #self.connect(dm_csi,blocks.stream_to_vector(gr.sizeof_float,dsubc),(demod,2))
        if(options.ideal):
            self.connect(dm_csi,blocks.stream_to_vector(gr.sizeof_float,dsubc),(demod,2))
        else:
            dm_csi_filter = self.dm_csi_filter = filter.single_pole_iir_filter_ff(0.01,dsubc)
            self.connect(self.ctf, self.dm_csi_filter,(demod,2))
            #log_to_file(self, dm_csi_filter, "data/softs_csi.float")
        #self.connect(dm_trig,(demod,3))
    else:
        demod = self._data_demodulator = generic_demapper_vcb(dsubc, config.frame_data_part)
    if options.benchmarking:
        # Do receiver benchmarking until the number of frames x symbols are collected
        self.connect(pda,blocks.head(gr.sizeof_gr_complex*dsubc, options.N*config.frame_data_blocks),demod)
    else:        
        self.connect(pda,demod)
    self.connect(bitloading_src,(demod,1))

    if(options.coding):
        ## Depuncturing
        if not options.nopunct:
            depuncturing = depuncture_ff(dsubc,0)
            frametrigger_bitmap_filter = blocks.vector_source_b([1,0],True)
            self.connect(bitloading_src,(depuncturing,1))
            self.connect(dp_trig,(depuncturing,2))

        ## Decoding
        chunkdivisor = int(numpy.ceil(config.frame_data_blocks/5.0))
        print "Number of chunks at Viterbi decoder: ", chunkdivisor
        decoding = self._data_decoder = ofdm.viterbi_combined_fb(fo,dsubc,-1,-1,2,chunkdivisor,[-1,-1,-1,1,1,-1,1,1],ofdm.TRELLIS_EUCLIDEAN)

        
        if options.log and options.coding:
            log_to_file(self, decoding, "data/decoded.char")
            if not options.nopunct:
                log_to_file(self, depuncturing, "data/vit_in.float")

        if not options.nopunct:
            if options.interleave:
                self.connect(demod,deinterlv,depuncturing,decoding)
            else:
                self.connect(demod,depuncturing,decoding)
        else:
            self.connect(demod,decoding)
        self.connect(self.bitcount_src, multiply_const_ii(1./chunkdivisor), (decoding,1))

    if options.scatterplot or options.scatter_plot_before_phase_tracking:
        if self.ideal2 is False:
            scatter_vec_elem = self._scatter_vec_elem = ofdm.vector_element(dsubc,40)
            scatter_s2v = self._scatter_s2v = blocks.stream_to_vector(gr.sizeof_gr_complex,config.frame_data_blocks)
    
            scatter_id_filt = skip(gr.sizeof_gr_complex*dsubc,config.frame_data_blocks)
            scatter_id_filt.skip_call(0)
            scatter_trig = [0]*config.frame_data_part
            scatter_trig[0] = 1
            scatter_trig = blocks.vector_source_b(scatter_trig,True)
            self.connect(scatter_trig,(scatter_id_filt,1))
            self.connect(scatter_vec_elem,scatter_s2v)
    
            if not options.scatter_plot_before_phase_tracking:
                print "Enabling Scatterplot for data subcarriers"
                self.connect(pda,scatter_id_filt,scatter_vec_elem)
                  # Work on this
                  #scatter_sink = ofdm.scatterplot_sink(dsubc)
                  #self.connect(pda,scatter_sink)
                  #self.connect(map_src,(scatter_sink,1))
                  #self.connect(dm_trig,(scatter_sink,2))
                  #print "Enabled scatterplot gui interface"
                self.zmq_probe_scatter = zeromq.pub_sink(gr.sizeof_gr_complex,config.frame_data_blocks, "tcp://*:5560")
                self.connect(scatter_s2v, blocks.keep_one_in_n(gr.sizeof_gr_complex*config.frame_data_blocks,20), self.zmq_probe_scatter)
            else:
                print "Enabling Scatterplot for data before phase tracking"
                inner_rx = inner_receiver.before_phase_tracking
                #scatter_sink2 = ofdm.scatterplot_sink(dsubc,"phase_tracking")
                op = copy.copy(options)
                op.enable_erasure_decision = False
                new_framesampler = ofdm_frame_sampler(op)
                self.connect( inner_rx, new_framesampler )
                self.connect( orig_frame_start, (new_framesampler,1) )
                new_ps_filter = pilot_subcarrier_filter()
                new_pb_filter = fbmc_pilot_block_filter()
    
                self.connect( (new_framesampler,1), (new_pb_filter,1) )
                self.connect( new_framesampler, new_pb_filter,
                             new_ps_filter, scatter_id_filt, scatter_vec_elem )
    
                #self.connect( new_ps_filter, scatter_sink2 )
                #self.connect( map_src, (scatter_sink2,1))
                #self.connect( dm_trig, (scatter_sink2,2))


    if options.log:
      if(options.coding):
          log_to_file(self, demod, "data/data_stream_out.float")
      else:
          data_f = gr.char_to_float()
          self.connect(demod,data_f)
          log_to_file(self, data_f, "data/data_stream_out.float")



    if options.sfo_feedback:
      used_id_bits = 8
      rep_id_bits = config.data_subcarriers/used_id_bits

      seed(1)
      whitener_pn = [randint(0,1) for i in range(used_id_bits*rep_id_bits)]

      id_enc = ofdm.repetition_encoder_sb(used_id_bits,rep_id_bits,whitener_pn)
      self.connect( self.id_dec, id_enc )

      id_mod = ofdm_bpsk_modulator(dsubc)
      self.connect( id_enc, id_mod )

      id_mod_conj = gr.conjugate_cc(dsubc)
      self.connect( id_mod, id_mod_conj )

      id_mult = blocks.multiply_vcc(dsubc)
      self.connect( id_bfilt, ( id_mult,0) )
      self.connect( id_mod_conj, ( id_mult,1) )

#      id_mult_avg = filter.single_pole_iir_filter_cc(0.01,dsubc)
#      self.connect( id_mult, id_mult_avg )

      id_phase = gr.complex_to_arg(dsubc)
      self.connect( id_mult, id_phase )

      log_to_file( self, id_phase, "data/id_phase.float" )

      est=ofdm.LS_estimator_straight_slope(dsubc)
      self.connect(id_phase,est)

      slope=blocks.multiply_const_ff(1e6/2/3.14159265)
      self.connect( (est,0), slope )

      log_to_file( self, slope, "data/slope.float" )
      log_to_file( self, (est,1), "data/offset.float" )

    # ------------------------------------------------------------------------ #




    # Display some information about the setup
    if config._verbose:
      self._print_verbage()

    ## debug logging ##
    if options.log:
#      log_to_file(self,self.ofdm_symbols,"data/unequalized_rx_ofdm_symbols.compl")
#      log_to_file(self,self.ofdm_symbols,"data/unequalized_rx_ofdm_symbols.float",mag=True)


      fftlen = 256
      my_window = window.hamming(fftlen) #.blackmanharris(fftlen)
      rxs_sampler = vector_sampler(gr.sizeof_gr_complex,fftlen)
      rxs_sampler_vect = concatenate([[1],[0]*49])
      rxs_trigger = blocks.vector_source_b(rxs_sampler_vect.tolist(),True)
      rxs_window = blocks.multiply_const_vcc(my_window)
      rxs_spectrum = gr.fft_vcc(fftlen,True,[],True)
      rxs_mag = gr.complex_to_mag(fftlen)
      rxs_avg = filter.single_pole_iir_filter_ff(0.01,fftlen)
      #rxs_logdb = blocks.nlog10_ff(20.0,fftlen,-20*log10(fftlen))
      rxs_logdb = gr.kludge_copy( gr.sizeof_float * fftlen )
      rxs_decimate_rate = gr.keep_one_in_n(gr.sizeof_float*fftlen,1)
      self.connect(rxs_trigger,(rxs_sampler,1))
      self.connect(self.input,rxs_sampler,rxs_window,
                   rxs_spectrum,rxs_mag,rxs_avg,rxs_logdb, rxs_decimate_rate)
      log_to_file( self, rxs_decimate_rate, "data/psd_input.float" )


    #output branches
    self.publish_rx_performance_measure()
Exemplo n.º 5
0
    def add_mobile_station(self, station_id):
        """
    Adds new receiver mobile station. Station ID must be unique. Initializes
    BER reference source.
    """

        # Initialize
        id_src = self._control._id_source
        dmux = self._data_multiplexer
        port = self._data_multiplexer_nextport
        self._data_multiplexer_nextport += 1

        # Setup
        ctrl_port = self._control.add_mobile_station(station_id)
        options = self._options
        if options.imgxfer:
            ref_src = ofdm.imgtransfer_src(options.img)
        else:
            ref_src = ber_reference_source(self._options)

        if (options.coding):
            ## Encoder
            encoder = self._encoder = ofdm.encoder_bb(fo, 0)
            unpack = self._unpack = blocks.unpack_k_bits_bb(2)

            ## Puncturing
            if not options.nopunct:
                puncturing = self._puncturing = puncture_bb(
                    options.subcarriers)
                #sah = gr.sample_and_hold_bb()
                #sah_trigger = blocks.vector_source_b([1,0],True)
                #decim_sah=gr.keep_one_in_n(gr.sizeof_char,2)
                self.connect(self._bitmap_trigger_puncturing, (puncturing, 2))
                frametrigger_bitmap_filter = blocks.vector_source_b([1, 0],
                                                                    True)
                bitmap_filter = self._puncturing_bitmap_src_filter = skip(
                    gr.sizeof_char * options.subcarriers,
                    2)  # skip_known_symbols(frame_length,subcarriers)
                bitmap_filter.skip_call(0)
                #self.connect(self._bitmap_src_puncturing,bitmap_filter,(puncturing,1))
                self.connect(self._map_src, bitmap_filter, (puncturing, 1))
                self.connect(frametrigger_bitmap_filter, (bitmap_filter, 1))
                #bmt = gr.char_to_float()
                #self.connect(bitmap_filter,blocks.vector_to_stream(gr.sizeof_char,options.subcarriers), bmt)
                #log_to_file(self, bmt, "data/bitmap_filter_tx.float")

            self.connect((self._control, ctrl_port), ref_src, encoder, unpack)
            if not options.nopunct:
                self.connect(unpack, puncturing, (dmux, port))
                #self.connect(sah_trigger, (sah,1))
            else:
                self.connect(unpack, (dmux, port))
        else:
            self.connect((self._control, ctrl_port), ref_src, (dmux, port))

        if options.log and options.coding:
            log_to_file(self, encoder, "data/encoder_out.char")
            log_to_file(self, ref_src, "data/reference_data_src.char")
            log_to_file(self, unpack, "data/encoder_unpacked_out.char")
            if not options.nopunct:
                log_to_file(self, puncturing, "data/puncturing_out.char")
Exemplo n.º 6
0
    def __init__(self, subc, vlen, ss):
        gr.hier_block2.__init__(
            self, "new_snr_estimator",
            gr.io_signature(1, 1, gr.sizeof_gr_complex * vlen),
            gr.io_signature(1, 1, gr.sizeof_float))

        print "Created Milan's SNR estimator"

        trigger = [0] * vlen
        trigger[0] = 1

        u = range(vlen / ss * (ss - 1))
        zeros_ind = map(lambda z: z + 1 + z / (ss - 1), u)

        skip1 = skip(gr.sizeof_gr_complex, vlen)
        for x in zeros_ind:
            skip1.skip(x)

        #print "skipped zeros",zeros_ind

        v = range(vlen / ss)
        ones_ind = map(lambda z: z * ss, v)

        skip2 = skip(gr.sizeof_gr_complex, vlen)
        for x in ones_ind:
            skip2.skip(x)

        #print "skipped ones",ones_ind

        v2s = gr.vector_to_stream(gr.sizeof_gr_complex, vlen)
        s2v1 = gr.stream_to_vector(gr.sizeof_gr_complex, vlen / ss)
        trigger_src_1 = gr.vector_source_b(trigger, True)

        s2v2 = gr.stream_to_vector(gr.sizeof_gr_complex, vlen / ss * (ss - 1))
        trigger_src_2 = gr.vector_source_b(trigger, True)

        mag_sq_ones = gr.complex_to_mag_squared(vlen / ss)
        mag_sq_zeros = gr.complex_to_mag_squared(vlen / ss * (ss - 1))

        filt_ones = gr.single_pole_iir_filter_ff(0.1, vlen / ss)
        filt_zeros = gr.single_pole_iir_filter_ff(0.1, vlen / ss * (ss - 1))

        sum_ones = vector_sum_vff(vlen / ss)
        sum_zeros = vector_sum_vff(vlen / ss * (ss - 1))

        D = gr.divide_ff()
        P = gr.multiply_ff()
        mult1 = gr.multiply_const_ff(ss - 1.0)
        add1 = gr.add_const_ff(-1.0)
        mult2 = gr.multiply_const_ff(1. / ss)
        scsnrdb = gr.nlog10_ff(10, 1, 0)
        filt_end = gr.single_pole_iir_filter_ff(0.1)

        self.connect(self, v2s, skip1, s2v1, mag_sq_ones, filt_ones, sum_ones)
        self.connect(trigger_src_1, (skip1, 1))

        self.connect(v2s, skip2, s2v2, mag_sq_zeros, filt_zeros, sum_zeros)
        self.connect(trigger_src_2, (skip2, 1))

        self.connect(sum_ones, D)
        self.connect(sum_zeros, (D, 1))
        self.connect(D, mult1, add1, mult2)

        self.connect(mult2, scsnrdb, filt_end, self)
Exemplo n.º 7
0
    def __init__(self, subc, vlen, ss):
        gr.hier_block2.__init__(
            self,
            "new_snr_estimator",
            gr.io_signature(2, 2, gr.sizeof_gr_complex * vlen),
            #gr.io_signature2(2,2,gr.sizeof_float*vlen,gr.sizeof_float*vlen/ss*(ss-1)))
            gr.io_signature2(2, 2, gr.sizeof_float * vlen, gr.sizeof_float))

        print "Created Milan's SINR estimator"

        trigger = [0] * vlen
        trigger[0] = 1

        v = range(vlen / ss)
        ones_ind = map(lambda z: z * ss, v)

        skip2_pr0 = skip(gr.sizeof_gr_complex, vlen)
        skip2_pr1 = skip(gr.sizeof_gr_complex, vlen)
        for x in ones_ind:
            skip2_pr0.skip(x)
            skip2_pr1.skip(x)

        #print "skipped ones",ones_ind

        v2s_pr0 = gr.vector_to_stream(gr.sizeof_gr_complex, vlen)
        v2s_pr1 = gr.vector_to_stream(gr.sizeof_gr_complex, vlen)

        s2v2_pr0 = gr.stream_to_vector(gr.sizeof_gr_complex,
                                       vlen / ss * (ss - 1))
        trigger_src_2_pr0 = gr.vector_source_b(trigger, True)
        s2v2_pr1 = gr.stream_to_vector(gr.sizeof_gr_complex,
                                       vlen / ss * (ss - 1))
        trigger_src_2_pr1 = gr.vector_source_b(trigger, True)

        mag_sq_zeros_pr0 = gr.complex_to_mag_squared(vlen / ss * (ss - 1))
        mag_sq_zeros_pr1 = gr.complex_to_mag_squared(vlen / ss * (ss - 1))

        filt_zeros_pr0 = gr.single_pole_iir_filter_ff(0.01,
                                                      vlen / ss * (ss - 1))
        filt_zeros_pr1 = gr.single_pole_iir_filter_ff(0.01,
                                                      vlen / ss * (ss - 1))
        v1 = vlen / ss * (ss - 1)
        vevc1 = [-1] * v1
        neg_nomin_z = gr.multiply_const_vff(vevc1)
        div_z = gr.divide_ff(vlen / ss * (ss - 1))
        on_zeros = gr.add_const_vff(vevc1)
        sum_zeros = add_vff(vlen / ss * (ss - 1))

        # For average
        sum_all = vector_sum_vff(vlen)
        mult = gr.multiply_const_ff(1. / vlen)
        scsnr_db_av = gr.nlog10_ff(10, 1, 0)
        filt_end_av = gr.single_pole_iir_filter_ff(0.1)

        self.connect((self, 0), v2s_pr0, skip2_pr0, s2v2_pr0, mag_sq_zeros_pr0,
                     filt_zeros_pr0)
        self.connect(trigger_src_2_pr0, (skip2_pr0, 1))

        self.connect((self, 1), v2s_pr1, skip2_pr1, s2v2_pr1, mag_sq_zeros_pr1,
                     filt_zeros_pr1)
        self.connect(trigger_src_2_pr1, (skip2_pr1, 1))

        # On zeros
        self.connect(filt_zeros_pr1, (sum_zeros, 0))
        self.connect(filt_zeros_pr0, neg_nomin_z, (sum_zeros, 1))
        self.connect(sum_zeros, div_z)
        self.connect(filt_zeros_pr0, (div_z, 1))

        scsnr_db = gr.nlog10_ff(10, vlen, 0)
        filt_end = gr.single_pole_iir_filter_ff(0.1, vlen)

        dd = []
        for i in range(vlen / ss):
            dd.extend([i * ss])
        #print dd
        interpolator = sinr_interpolator(vlen, ss, dd)

        self.connect(div_z, interpolator, filt_end, scsnr_db, self)
        self.connect(interpolator, sum_all, mult, scsnr_db_av, filt_end_av,
                     (self, 1))
Exemplo n.º 8
0
  def __init__(self, subc, vlen, ss):
    gr.hier_block2.__init__(self, "new_snr_estimator",
        gr.io_signature(1,1,gr.sizeof_gr_complex*vlen),
        gr.io_signature(1,1,gr.sizeof_float))

    print "Created Milan's SNR estimator"

    trigger = [0]*vlen
    trigger[0] = 1


    u = range (vlen/ss*(ss-1))
    zeros_ind= map(lambda z: z+1+z/(ss-1),u)

    skip1 = skip(gr.sizeof_gr_complex,vlen)
    for x in zeros_ind:
      skip1.skip(x)

    #print "skipped zeros",zeros_ind

    v = range (vlen/ss)
    ones_ind= map(lambda z: z*ss,v)

    skip2 = skip(gr.sizeof_gr_complex,vlen)
    for x in ones_ind:
      skip2.skip(x)

    #print "skipped ones",ones_ind

    v2s = gr.vector_to_stream(gr.sizeof_gr_complex,vlen)
    s2v1 = gr.stream_to_vector(gr.sizeof_gr_complex,vlen/ss)
    trigger_src_1 = gr.vector_source_b(trigger,True)

    s2v2 = gr.stream_to_vector(gr.sizeof_gr_complex,vlen/ss*(ss-1))
    trigger_src_2 = gr.vector_source_b(trigger,True)

    mag_sq_ones = gr.complex_to_mag_squared(vlen/ss)
    mag_sq_zeros = gr.complex_to_mag_squared(vlen/ss*(ss-1))

    filt_ones = gr.single_pole_iir_filter_ff(0.1,vlen/ss)
    filt_zeros = gr.single_pole_iir_filter_ff(0.1,vlen/ss*(ss-1))

    sum_ones = vector_sum_vff(vlen/ss)
    sum_zeros = vector_sum_vff(vlen/ss*(ss-1))

    D = gr.divide_ff()
    P = gr.multiply_ff()
    mult1 = gr.multiply_const_ff(ss-1.0)
    add1 = gr.add_const_ff(-1.0)
    mult2 = gr.multiply_const_ff(1./ss)
    scsnrdb = gr.nlog10_ff(10,1,0)
    filt_end = gr.single_pole_iir_filter_ff(0.1)

    self.connect(self,v2s,skip1,s2v1,mag_sq_ones,filt_ones,sum_ones)
    self.connect(trigger_src_1,(skip1,1))

    self.connect(v2s,skip2,s2v2,mag_sq_zeros,filt_zeros,sum_zeros)
    self.connect(trigger_src_2,(skip2,1))

    self.connect(sum_ones,D)
    self.connect(sum_zeros,(D,1))
    self.connect(D,mult1,add1,mult2)

    self.connect(mult2,scsnrdb,filt_end,self)
Exemplo n.º 9
0
  def __init__(self, subc, vlen, ss):
    gr.hier_block2.__init__(self, "new_snr_estimator",
        gr.io_signature(2,2,gr.sizeof_gr_complex*vlen),
        #gr.io_signature2(2,2,gr.sizeof_float*vlen,gr.sizeof_float*vlen/ss*(ss-1)))
        gr.io_signature2(2,2,gr.sizeof_float*vlen,gr.sizeof_float))

    print "Created Milan's SINR estimator"

    trigger = [0]*vlen
    trigger[0] = 1

    v = range (vlen/ss)
    ones_ind= map(lambda z: z*ss,v)

    skip2_pr0 = skip(gr.sizeof_gr_complex,vlen)
    skip2_pr1 = skip(gr.sizeof_gr_complex,vlen)
    for x in ones_ind:
      skip2_pr0.skip(x)
      skip2_pr1.skip(x)

    #print "skipped ones",ones_ind

    v2s_pr0 = gr.vector_to_stream(gr.sizeof_gr_complex,vlen)
    v2s_pr1 = gr.vector_to_stream(gr.sizeof_gr_complex,vlen)

    s2v2_pr0 = gr.stream_to_vector(gr.sizeof_gr_complex,vlen/ss*(ss-1))
    trigger_src_2_pr0 = gr.vector_source_b(trigger,True)
    s2v2_pr1 = gr.stream_to_vector(gr.sizeof_gr_complex,vlen/ss*(ss-1))
    trigger_src_2_pr1 = gr.vector_source_b(trigger,True)

    mag_sq_zeros_pr0 = gr.complex_to_mag_squared(vlen/ss*(ss-1))
    mag_sq_zeros_pr1 = gr.complex_to_mag_squared(vlen/ss*(ss-1))


    filt_zeros_pr0 = gr.single_pole_iir_filter_ff(0.01,vlen/ss*(ss-1))
    filt_zeros_pr1 = gr.single_pole_iir_filter_ff(0.01,vlen/ss*(ss-1))
    v1 = vlen/ss*(ss-1)
    vevc1 =[-1]*v1
    neg_nomin_z = gr.multiply_const_vff(vevc1)
    div_z=gr.divide_ff(vlen/ss*(ss-1))
    on_zeros = gr.add_const_vff(vevc1)
    sum_zeros = add_vff(vlen/ss*(ss-1))
    
    # For average
    sum_all = vector_sum_vff(vlen)
    mult = gr.multiply_const_ff(1./vlen)
    scsnr_db_av = gr.nlog10_ff(10,1,0)
    filt_end_av = gr.single_pole_iir_filter_ff(0.1)


    self.connect((self,0),v2s_pr0,skip2_pr0,s2v2_pr0,mag_sq_zeros_pr0,filt_zeros_pr0)
    self.connect(trigger_src_2_pr0,(skip2_pr0,1))



    self.connect((self,1),v2s_pr1,skip2_pr1,s2v2_pr1,mag_sq_zeros_pr1,filt_zeros_pr1)
    self.connect(trigger_src_2_pr1,(skip2_pr1,1))


    # On zeros
    self.connect(filt_zeros_pr1,(sum_zeros,0))
    self.connect(filt_zeros_pr0,neg_nomin_z,(sum_zeros,1))
    self.connect(sum_zeros,div_z)
    self.connect(filt_zeros_pr0,(div_z,1))


    scsnr_db = gr.nlog10_ff(10,vlen,0)
    filt_end = gr.single_pole_iir_filter_ff(0.1,vlen)



    dd = []
    for i in range (vlen/ss):
        dd.extend([i*ss])
    #print dd
    interpolator = sinr_interpolator(vlen, ss,dd)

    self.connect(div_z,interpolator,filt_end,scsnr_db,self)
    self.connect(interpolator,sum_all,mult,scsnr_db_av,filt_end_av,(self,1))