def __init__(self, options, parent): ''' See below for what options should hold ''' gr.hier_block2.__init__(self, "transmit_path", gr.io_signature(0, 0, 0), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature options = copy.copy(options) # make a copy so we can destructively modify self._bitrate = options.bitrate # desired bit rate #self._inter = options.inter # Decimating rate for the USRP (prelim) self._samples_per_symbol = options.samples_per_symbol # desired samples/symbol self._down_sample_rate = options.down_sample_rate self._verbose = options.verbose self._tx_amplitude = options.tx_amplitude # digital amplitude sent to USRP self._use_whitener_offset = options.use_whitener_offset # increment start of whitener XOR data self._access_code = packet_utils.conv_packed_binary_string_to_1_0_string(default_ola_spade_code) self._subchannel = options.subchannel self._msgq_limit = 4 self.parent = parent # Turn it into NRZ data. self.nrz = gr.bytes_to_syms() self.sqwave = (1,) * self._samples_per_symbol # rectangular window self.gaussian_filter = gr.interp_fir_filter_fff(self._samples_per_symbol, self.sqwave) #Sensitivity will be seletected by set_sensitivity function in main loop self.sensitivity_a = (2 *pi * self._subchannel) / self._samples_per_symbol # phase change per bit = pi / 2 (for BFSK) self.sensitivity_b = (2 *pi * (self._subchannel)) / self._samples_per_symbol # phase change per bit = pi / 2 (for BFSK) self._pad_for_usrp = True self._use_whitener_offset = False self._whitener_offset = 0 # TODO # BUG : Improve or Implement Stream Selector!!!! (Check the new GNU Radio blocks!!!) # ============================================================================= # The first flowgraph for Digital Only Modulation # ============================================================================= self._pkt_input = gr.message_source(gr.sizeof_char, self._msgq_limit) # accepts messages from the outside world self.fmmod = gtlib.bfsk_modulator_fc(self.sensitivity_a,self.sensitivity_b) # BFSK modulation self.amp = gr.multiply_const_cc(1) # (Note that on the RFX cards this is a nop.) self.amp_2 = gr.multiply_const_cc(1) # (Sub channel correction) if self._subchannel >= 1 and self._subchannel <= 4: self.amp_2.set_k(pow(1.2,(float(self._subchannel)-1))) #self.timetag_inserter = gtlib.usrp_timetag_insert() if self._verbose: self._print_verbage() # Display some information about the setup # ============================================================================= # Flowgraph connection # ============================================================================= self.connect(self._pkt_input, self.nrz, self.gaussian_filter,self.fmmod,self.amp, self.amp_2, self) self.set_tx_amplitude(self._tx_amplitude)
def __init__(self, rx_callback, packet, options): gr.hier_block2.__init__(self, "receive_path", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(0, 0, 0)) # Output signature self.options = copy.copy(options) # make a copy so we can destructively modify self._verbose = self.options.verbose self._samples_per_symbol = self.options.samples_per_symbol # desired samples/symbol self._order_of_subchannels= self.options.order_of_subchannels self._rx_callback = rx_callback # this callback is fired when there's a packet available self._packet = packet # Options for Transmit Time Synchronization self._sfo = self.options.sfo # Sampling Frequency Offset Compensation self._bpf = self.options.bpf # Bandpass Filtering self._gamma = self.options.gamma self._access_code = packet_utils.conv_packed_binary_string_to_1_0_string(default_ola_spade_code) self._threshold = 2 self._down_sample_rate = self.options.down_sample_rate self.n_filter_taps = int (self._samples_per_symbol / self._down_sample_rate) #self._cs_upper_db = -11 #self._cs_lower_db = -11 # Display some information about the setup if self._verbose: self._print_verbage() self._rcvd_pktq = gr.msg_queue() # holds packets from the PHY self.framer_sink = gtlib.framer_sink_2(self._sfo,self._rcvd_pktq,False) self.ncbfsk_demod = gtlib.ncbfsk_freq_diversity(self.n_filter_taps, self._gamma,self._access_code,self._threshold) #self.timetag_extractor = gtlib.usrp_timetag_extract(self._cs_upper_db,self._cs_lower_db, 8*self._samples_per_symbol, self._down_sample_rate) self._bitrate = 256000 #self.timetag_extractor.config_clock(self._bitrate*256, self._bitrate) self.ncbfsk_demod.config_timestamp(0) unlock_func = self.ncbfsk_demod.unlock() phase_1 = phase_2 = phase_3 = phase_4 = 0 self.amp = gr.multiply_const_cc(10) sensitivity_1 = (2 *pi * 1) / self.n_filter_taps sensitivity_2 = (2 *pi * 2) / self.n_filter_taps sensitivity_3 = (2 *pi * 3) / self.n_filter_taps sensitivity_4 = (2 *pi * 4) / self.n_filter_taps #Matched Filter Taps for diversity channel #1 self.taps_1_a = [1,] * self.n_filter_taps self.taps_1_b = [1,] * self.n_filter_taps #Matched Filter Taps for diversity channel #2 self.taps_2_a = [1,] * self.n_filter_taps self.taps_2_b = [1,] * self.n_filter_taps #Matched Filter Taps for diversity channel #3 self.taps_3_a = [1,] * self.n_filter_taps self.taps_3_b = [1,] * self.n_filter_taps #Matched Filter Taps for diversity channel #4 self.taps_4_a = [1,] * self.n_filter_taps self.taps_4_b = [1,] * self.n_filter_taps #Magnitude self.abs_1_a = gr.complex_to_mag() self.abs_1_b = gr.complex_to_mag() self.abs_2_a = gr.complex_to_mag() self.abs_2_b = gr.complex_to_mag() self.abs_3_a = gr.complex_to_mag() self.abs_3_b = gr.complex_to_mag() self.abs_4_a = gr.complex_to_mag() self.abs_4_b = gr.complex_to_mag() for i in range(0,self.n_filter_taps): self.taps_1_a[i] = (math.cos(phase_1) + 1j* (math.sin(phase_1))) / self.n_filter_taps self.taps_1_b[i] = (math.cos(phase_1) - 1j* (math.sin(phase_1))) / self.n_filter_taps self.taps_2_a[i] = (math.cos(phase_2) + 1j* (math.sin(phase_2))) / self.n_filter_taps self.taps_2_b[i] = (math.cos(phase_2) - 1j* (math.sin(phase_2))) / self.n_filter_taps self.taps_3_a[i] = (math.cos(phase_3) + 1j* (math.sin(phase_3))) / self.n_filter_taps self.taps_3_b[i] = (math.cos(phase_3) - 1j* (math.sin(phase_3))) / self.n_filter_taps self.taps_4_a[i] = (math.cos(phase_4) + 1j* (math.sin(phase_4))) / self.n_filter_taps self.taps_4_b[i] = (math.cos(phase_4) - 1j* (math.sin(phase_4))) / self.n_filter_taps phase_1 = phase_1 + sensitivity_1 phase_2 = phase_2 + sensitivity_2 phase_3 = phase_3 + sensitivity_3 phase_4 = phase_4 + sensitivity_4 self.match_filter_1_a = gr.fir_filter_ccc(1,self.taps_1_a) self.match_filter_1_b = gr.fir_filter_ccc(1,self.taps_1_b) self.match_filter_2_a = gr.fir_filter_ccc(1,self.taps_2_a) self.match_filter_2_b = gr.fir_filter_ccc(1,self.taps_2_b) self.match_filter_3_a = gr.fir_filter_ccc(1,self.taps_3_a) self.match_filter_3_b = gr.fir_filter_ccc(1,self.taps_3_b) self.match_filter_4_a = gr.fir_filter_ccc(1,self.taps_4_a) self.match_filter_4_b = gr.fir_filter_ccc(1,self.taps_4_b) self.sub = gr.sub_ff() self.adder_a = gr.add_ff() self.adder_b = gr.add_ff() fs = gr.null_sink(gr.sizeof_float) self.connect(self,self.amp) # Data Stream print '>>> [Receive Path] Order of Subchannels=', self._order_of_subchannels if self._order_of_subchannels > 0: print '>>> [Receive Path] Setup first subchannel' self.connect(self.amp,self.match_filter_1_a,self.abs_1_a,(self.adder_a,0)) self.connect(self.amp,self.match_filter_1_b,self.abs_1_b,(self.adder_b,0)) if self._order_of_subchannels > 1: print '>>> [Receive Path] Setup second subchannel' self.connect(self.amp,self.match_filter_2_a,self.abs_2_a,(self.adder_a,1)) self.connect(self.amp,self.match_filter_2_b,self.abs_2_b,(self.adder_b,1)) if self._order_of_subchannels > 2: print '>>> [Receive Path] Setup third subchannel' self.connect(self.amp,self.match_filter_3_a,self.abs_3_a,(self.adder_a,2)) self.connect(self.amp,self.match_filter_3_b,self.abs_3_b,(self.adder_b,2)) if self._order_of_subchannels > 3: print '>>> [Receive Path] Setup fourth subchannel' self.connect(self.amp,self.match_filter_4_a,self.abs_4_a,(self.adder_a,3)) self.connect(self.amp,self.match_filter_4_b,self.abs_4_b,(self.adder_b,3)) self.connect(self.adder_a,(self.sub,0)) self.connect(self.adder_b,(self.sub,1)) self.connect(self.sub,self.ncbfsk_demod) self.connect(self.ncbfsk_demod,self.framer_sink) # Time-tag Stream #self.connect((self.timetag_extractor,0),(self.ncbfsk_demod,0),(self.framer_sink,0)) #self.connect((self.timetag_extractor,0),gr.null_sink(8)) self._watcher = _queue_watcher_thread_demod_pkts_ncbfsk(self._rcvd_pktq, rx_callback, self._packet, self.ncbfsk_demod, self.framer_sink, self) if options.log: self.connect(self, gr.file_sink(8,'e100_samples.dat'))