def __init__(self, uhd_address, options): gr.top_block.__init__(self) self.uhd_addr = uhd_address self.freq = options.freq self.samp_rate = options.samp_rate self.gain = options.gain self.threshold = options.threshold self.trigger = options.trigger self.uhd_src = uhd.single_usrp_source( device_addr=self.uhd_addr, io_type=uhd.io_type_t.COMPLEX_FLOAT32, num_channels=1, ) self.uhd_src.set_samp_rate(self.samp_rate) self.uhd_src.set_center_freq(self.freq, 0) self.uhd_src.set_gain(self.gain, 0) taps = firdes.low_pass_2(1, 1, 0.4, 0.1, 60) self.chanfilt = gr.fir_filter_ccc(10, taps) self.tagger = gr.burst_tagger(gr.sizeof_gr_complex) # Dummy signaler to collect a burst on known periods data = 1000*[0,] + 1000*[1,] self.signal = gr.vector_source_s(data, True) # Energy detector to get signal burst ## use squelch to detect energy self.det = gr.simple_squelch_cc(self.threshold, 0.01) ## convert to mag squared (float) self.c2m = gr.complex_to_mag_squared() ## average to debounce self.avg = gr.single_pole_iir_filter_ff(0.01) ## rescale signal for conversion to short self.scale = gr.multiply_const_ff(2**16) ## signal input uses shorts self.f2s = gr.float_to_short() # Use file sink burst tagger to capture bursts self.fsnk = gr.tagged_file_sink(gr.sizeof_gr_complex, self.samp_rate) ################################################## # Connections ################################################## self.connect((self.uhd_src, 0), (self.tagger, 0)) self.connect((self.tagger, 0), (self.fsnk, 0)) if self.trigger: # Connect a dummy signaler to the burst tagger self.connect((self.signal, 0), (self.tagger, 1)) else: # Connect an energy detector signaler to the burst tagger self.connect(self.uhd_src, self.det) self.connect(self.det, self.c2m, self.avg, self.scale, self.f2s) self.connect(self.f2s, (self.tagger, 1))
def __init__(self, uhd_address, options): gr.top_block.__init__(self) self.uhd_addr = uhd_address self.freq = options.freq self.samp_rate = options.samp_rate self.gain = options.gain self.threshold = options.threshold self.trigger = options.trigger self.uhd_src = uhd.single_usrp_source( device_addr=self.uhd_addr, stream_args=uhd.stream_args('fc32')) self.uhd_src.set_samp_rate(self.samp_rate) self.uhd_src.set_center_freq(self.freq, 0) self.uhd_src.set_gain(self.gain, 0) taps = firdes.low_pass_2(1, 1, 0.4, 0.1, 60) self.chanfilt = gr.fir_filter_ccc(10, taps) self.tagger = gr.burst_tagger(gr.sizeof_gr_complex) # Dummy signaler to collect a burst on known periods data = 1000 * [ 0, ] + 1000 * [ 1, ] self.signal = gr.vector_source_s(data, True) # Energy detector to get signal burst ## use squelch to detect energy self.det = gr.simple_squelch_cc(self.threshold, 0.01) ## convert to mag squared (float) self.c2m = gr.complex_to_mag_squared() ## average to debounce self.avg = gr.single_pole_iir_filter_ff(0.01) ## rescale signal for conversion to short self.scale = gr.multiply_const_ff(2**16) ## signal input uses shorts self.f2s = gr.float_to_short() # Use file sink burst tagger to capture bursts self.fsnk = gr.tagged_file_sink(gr.sizeof_gr_complex, self.samp_rate) ################################################## # Connections ################################################## self.connect((self.uhd_src, 0), (self.tagger, 0)) self.connect((self.tagger, 0), (self.fsnk, 0)) if self.trigger: # Connect a dummy signaler to the burst tagger self.connect((self.signal, 0), (self.tagger, 1)) else: # Connect an energy detector signaler to the burst tagger self.connect(self.uhd_src, self.det) self.connect(self.det, self.c2m, self.avg, self.scale, self.f2s) self.connect(self.f2s, (self.tagger, 1))
def main(): data = scipy.arange(0, 32000, 1).tolist() trig = 100*[0,] + 100*[1,] src = gr.vector_source_s(data, True) trigger = gr.vector_source_s(trig, True) thr = gr.throttle(gr.sizeof_short, 10e3) ann = gr.annotator_alltoall(1000000, gr.sizeof_short) tagger = gr.burst_tagger(gr.sizeof_short) fsnk = gr.tagged_file_sink(gr.sizeof_short, 1) tb = gr.top_block() tb.connect(src, thr, (tagger, 0)) tb.connect(trigger, (tagger, 1)) tb.connect(tagger, fsnk) tb.run()
def main(): data = scipy.arange(0, 32000, 1).tolist() trig = 100 * [ 0, ] + 100 * [ 1, ] src = gr.vector_source_s(data, True) trigger = gr.vector_source_s(trig, True) thr = gr.throttle(gr.sizeof_short, 10e3) ann = gr.annotator_alltoall(1000000, gr.sizeof_short) tagger = gr.burst_tagger(gr.sizeof_short) fsnk = gr.tagged_file_sink(gr.sizeof_short, 1) tb = gr.top_block() tb.connect(src, thr, (tagger, 0)) tb.connect(trigger, (tagger, 1)) tb.connect(tagger, fsnk) tb.run()
def __init__(self, options, msgq_limit=2, pad_for_usrp=True): """ Hierarchical block for sending packets Packets to be sent are enqueued by calling send_pkt. The output is the complex modulated signal at baseband. @param options: pass modulation options from higher layers (fft length, occupied tones, etc.) @param msgq_limit: maximum number of messages in message queue @type msgq_limit: int @param pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples """ gr.hier_block2.__init__(self, "ofdm_mod", gr.io_signature(0, 0, 0), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature self._pad_for_usrp = pad_for_usrp self._modulation = options.modulation self._fft_length = options.fft_length self._occupied_tones = options.occupied_tones self._cp_length = options.cp_length # apurv++ start # self._id = options.id self._fec_n = options.fec_n self._fec_k = options.fec_k self._batch_size = options.batch_size self._ack = options.ack if(self._fec_n < self._fec_k): print "ERROR: K > N in FEC!\n" exit(0); # apurv++ end # win = [] #[1 for i in range(self._fft_length)] # Use freq domain to get doubled-up known symbol for correlation in time domain zeros_on_left = int(math.ceil((self._fft_length - self._occupied_tones)/2.0)) # apurv: use the preamble as a function of hop number # #ksfreq = known_symbols_4512_3[0:self._occupied_tones] start_index = (options.hop) * self._occupied_tones ksfreq = known_symbols_4512_3[start_index:start_index + self._occupied_tones] # allow another full preamble (no intermediate 0s for accurate channel estimate/snr measurement) preamble2_offset = 10*self._occupied_tones; ksfreq2 = known_symbols_4512_3[preamble2_offset:preamble2_offset+self._occupied_tones] ''' # inserting zeros in every other frequency bin # for i in range(len(ksfreq)): if((zeros_on_left + i) & 1): ksfreq[i] = 0 ''' # hard-coded known symbols preambles = (ksfreq, ksfreq2, ksfreq2) padded_preambles = list() for pre in preambles: padded = self._fft_length*[0,] padded[zeros_on_left : zeros_on_left + self._occupied_tones] = pre padded_preambles.append(padded) symbol_length = options.fft_length + options.cp_length mods = {"bpsk": 2, "qpsk": 4, "8psk": 8, "qam8": 8, "qam16": 16, "qam64": 64, "qam256": 256} hdr_rot = 1 hdr_arity = mods["bpsk"] hdr_constel = psk.psk_constellation(hdr_arity) hdr_rotated_const = map(lambda pt: pt * hdr_rot, hdr_constel.points()) data_rot = 1 data_arity = mods[self._modulation] if self._modulation == "qpsk": data_rot = (0.707+0.707j) if(self._modulation.find("psk") >= 0): data_constel = psk.psk_constellation(data_arity) data_rotated_const = map(lambda pt: pt * data_rot, data_constel.points()) elif(self._modulation.find("qam") >= 0): data_constel = qam.qam_constellation(data_arity) data_rotated_const = map(lambda pt: pt * data_rot, data_constel.points()) self._bits_per_symbol = int(math.log(mods[self._modulation], 2)) # just a useless parameter now # self._pkt_input = digital_swig.ofdm_mapper_bcv(hdr_rotated_const, data_rotated_const, padded_preambles,msgq_limit, options.occupied_tones, options.fft_length, options.tdma, options.proto, options.ack, options.id, options.src, options.batch_size, options.dst_id, options.fec_n, options.fec_k) self.ifft = gr.fft_vcc(self._fft_length, False, win, True) self.cp_adder = digital_swig.ofdm_cyclic_prefixer(self._fft_length, symbol_length) self.scale = gr.multiply_const_cc(1.0 / math.sqrt(self._fft_length)) self.burst_tagger = gr.burst_tagger(gr.sizeof_gr_complex) # 1 sample use_burst_tagger = 1 manual = options.tx_manual if manual == 0: if use_burst_tagger == 0: self.connect((self._pkt_input, 0), self.ifft, self.cp_adder, self.scale, self) else: # some burst tagger connections # self.connect((self._pkt_input, 0), self.ifft, self.cp_adder, self.burst_tagger, self.scale, self) self.connect((self._pkt_input, 1), (self.cp_adder, 1), (self.burst_tagger,1)) # Connect Apurv's trigger data to the burst tagger self.connect((self._pkt_input, 2), (self.cp_adder, 2)) # CDD elif manual == 1: # punt the pkt_input and use file source # self.connect(gr.file_source(gr.sizeof_gr_complex*options.fft_length, "fwd_tx_data.dat"), self.cp_adder, self.scale, self) self.connect(self.scale, gr.file_sink(gr.sizeof_gr_complex, "ofdm_fwd.dat")) if options.verbose: self._print_verbage() if options.log: self.connect(self._pkt_input, gr.file_sink(gr.sizeof_gr_complex*options.fft_length, "ofdm_mapper_c.dat")) self.connect(self.ifft, gr.file_sink(gr.sizeof_gr_complex*options.fft_length, "ofdm_ifft_c.dat")) self.connect(self.cp_adder, gr.file_sink(gr.sizeof_gr_complex, "ofdm_cp_adder_c.dat")) #self.connect(self.cp_adder, gr.file_sink(gr.sizeof_gr_complex, "ofdm_cp_adder_c.dat")) self.connect(self._pkt_input, gr.file_sink(gr.sizeof_gr_complex*options.fft_length, "symbols_src.dat")) self.connect((self._pkt_input, 3), gr.file_sink(gr.sizeof_char, "timing.dat")) self.connect((self._pkt_input, 4), gr.file_sink(gr.sizeof_char*options.fft_length, "timing_src.dat"))
def __init__(self, frequency, sample_rate, uhd_address="192.168.10.2", trigger=False): gr.top_block.__init__(self) self.freq = frequency self.samp_rate = sample_rate self.uhd_addr = uhd_address self.gain = 32 self.trigger = trigger self.uhd_src = uhd.single_usrp_source( device_addr=self.uhd_addr, io_type=uhd.io_type_t.COMPLEX_FLOAT32, num_channels=1, ) self.uhd_src.set_samp_rate(self.samp_rate) self.uhd_src.set_center_freq(self.freq, 0) self.uhd_src.set_gain(self.gain, 0) taps = firdes.low_pass_2(1, 1, 0.4, 0.1, 60) self.chanfilt = gr.fir_filter_ccc(10, taps) self.ann0 = gr.annotator_alltoall(100000, gr.sizeof_gr_complex) self.tagger = gr.burst_tagger(gr.sizeof_gr_complex) # Dummy signaler to collect a burst on known periods data = 1000 * [ 0, ] + 1000 * [ 1, ] self.signal = gr.vector_source_s(data, True) # Energy detector to get signal burst self.c2m = gr.complex_to_mag_squared() self.iir = gr.single_pole_iir_filter_ff(0.0001) self.sub = gr.sub_ff() self.mult = gr.multiply_const_ff(32768) self.f2s = gr.float_to_short() self.fsnk = gr.tagged_file_sink(gr.sizeof_gr_complex, self.samp_rate) ################################################## # Connections ################################################## self.connect((self.uhd_src, 0), (self.tagger, 0)) self.connect((self.tagger, 0), (self.fsnk, 0)) if self.trigger: # Connect a dummy signaler to the burst tagger self.connect((self.signal, 0), (self.tagger, 1)) else: # Connect an energy detector signaler to the burst tagger self.connect((self.uhd_src, 0), (self.c2m, 0)) self.connect((self.c2m, 0), (self.sub, 0)) self.connect((self.c2m, 0), (self.iir, 0)) self.connect((self.iir, 0), (self.sub, 1)) self.connect((self.sub, 0), (self.mult, 0)) self.connect((self.mult, 0), (self.f2s, 0)) self.connect((self.f2s, 0), (self.tagger, 1))