def start_tdma_net(self, start_time, burst_duration, idle_duration): # specify the tdma pulse parameters and connect the # pulse source to usrp sinker also specify the usrp source # with the specified start time if (self.n_devices > 0): time_slot = (burst_duration + idle_duration)/NETWORK_SIZE #print 'base_s_time = %.7f' %start_time for i in range(self.n_devices): s_time = uhd.time_spec_t(start_time + time_slot*(NODES_PC*self._node_id + i)) #print 'specified_time = %.7f' %s_time.get_real_secs() local_time = self.rcvs[i].get_time_now().get_real_secs() print 'current time 1 = %.7f' %local_time # Set the start time for sensors self.rcvs[i].set_start_time(uhd.time_spec_t(start_time)) else: exit("no devices on this node!") # start the flow graph and all the sensors self.start() time.sleep(5) for i in range(self.n_devices): current_time = self.rcvs[i].get_time_now().get_real_secs() print "current time 2 = %.7f" %current_time #print "base_s_time = %.7f" %start_time self.rcvs[i].start() #start the transmitting of data packets self.sinks[i].start()
def syncSDRTime(self, arg): if self.options.ignore_ntp != True: x = ntplib.NTPClient() cur_time = x.request('europe.pool.ntp.org').tx_time self.u.set_time_unknown_pps(uhd.time_spec_t(int(cur_time)+1)) else: self.u.set_time_unknown_pps(uhd.time_spec_t(int(time.time()+1))) #Hack to get the USRP to push an rx_time tag if self.options.test == False and self.options.fromfile == False and self.options.frombitlog == False: self.u.set_samp_rate(self._samples_per_second)
def test_time_spec_t (self): seconds = 42.0 time = uhd.time_spec_t(seconds) twice_time = time + time; zero_time = time - time; self.assertEqual(time.get_real_secs() * 2, seconds * 2 ) self.assertEqual(time.get_real_secs() - time.get_real_secs() , 0.0)
def __init__(self, sample_rate, center_freq, gain, device_addr=""): gr.top_block.__init__(self) # Make a local QtApp so we can start it from our side self.qapp = QtGui.QApplication(sys.argv) fftsize = 2048 self.src = uhd.single_usrp_source( device_addr="serial=4cfc2b4d", io_type=uhd.io_type_t.COMPLEX_FLOAT32, num_channels=1 ) self.src.set_samp_rate(sample_rate) self.src.set_center_freq(center_freq, 0) self.src.set_gain(gain, 0) self.src.set_time_now(uhd.time_spec_t(0.0)) self.snk = qtgui.sink_c( fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, center_freq, self.src.get_samp_rate(), "Realtime Display" ) cmd = uhd.cmd_t(uhd.stream_cmd_t.STREAM_MODE_NUM_SAMPS_AND_DONE) self.connect(self.src, self.snk) # Tell the sink we want it displayed self.pyobj = sip.wrapinstance(self.snk.pyqwidget(), QtGui.QWidget) self.pyobj.show()
def start_streaming(self): if self._node_type == CLUSTER_HEAD: #self._socket_ctrl_chan._sock_client._socket.sendto("message from cluster head\n", ('<broadcast>', NODE_PORT)) hostname = socket.gethostname() current_time = self.rcvs[0].get_time_now().get_real_secs() start_time_v = current_time + 10 print "cluster head current time %.7f" %current_time start_time = struct.pack('!d', current_time + 10) burst_duration = struct.pack('!d', BURST_LEN) t_slot = 0.010 # tdma slot length idle_duration = struct.pack('!d', t_slot*(NETWORK_SIZE - 1) + t_slot - BURST_LEN) payload = 'cmd' + ':' + 'start' + ':' + start_time + ':' + burst_duration + ':' + idle_duration #print hostname #self._socket_ctrl_chan._sock_client._socket.sendto(hostname, ('<broadcast>', NODE_PORT)) self._socket_ctrl_chan._sock_client._socket.sendto(payload, ('<broadcast>', NODE_PORT)) #self.rcvs[0].set_start_time(uhd.time_spec_t(start_time_v)) self.rcvs[0].start() else: # CLUSTER_NODE will be responsible for tdma transmitting and receiving if DEBUG == 1: stime = self.rcvs[0].get_time_now().get_real_secs() #for i in range(NODES_PC): self.rcvs[0].set_start_time(uhd.time_spec_t(stime + 2)) self.start() time.sleep(5) self.rcvs[0].start()
def start_streaming(self): stime = self.source.u.get_time_now().get_real_secs() self.source.u.set_start_time(uhd.time_spec_t(stime + 2)) #self.start() self.source.u.start() print 'start streaming' ############################## #try: # Create a TCP/IP socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Connect the socket to the port where the server is listening server_address = ('cri-node-10.ch.dhcp.tntech.edu', 10000) print >>sys.stderr, 'connecting to %s port %s' % server_address sock.connect(server_address) # Send data message_start_stream = 'start streaming' print >>sys.stderr, 'sending "%s"' % message_start_stream sock.sendall(message_start_stream) # Look for the response amount_received = 0 amount_expected = len(message_start_stream) while amount_received < amount_expected: data = sock.recv(16) amount_received += len(data) print >>sys.stderr, 'received "%s"' % data
def _variable_function_probe_0_2_probe(): while True: val = self.uhd_usrp_sink.set_time_now(uhd.time_spec_t(0.0)) try: self.set_variable_function_probe_0_2(val) except AttributeError: pass time.sleep(1.0 / (1e-9))
def _variable_function_probe_0_0_0_0_probe(): while True: val = self.uhd_usrp_source.set_start_time(uhd.time_spec_t(0.5)) try: self.set_variable_function_probe_0_0_0_0(val) except AttributeError: pass time.sleep(1.0 / (1e-9))
def stream_loop(self): print "enter stream_loop" for i in range(self._itera): t = self._tb.uhd_usrp_source_0.get_time_now(0).get_real_secs() + 4 print t self._tb.uhd_usrp_source_0.set_start_time(uhd.time_spec_t(t)) samps = self._tb.uhd_usrp_source_0.finite_acquisition(8) print samps
def timing(self): # Code based on code from: # http://lists.ettus.com/pipermail/usrp-users_lists.ettus.com/attachments/20150115/66ac59c6/attachment-0002.html # Get user time print('Type in desired start time (min only)') user_start_time = (int(input()), ) # Convert user time to Seconds local_time = time.time() user_time = time.localtime(local_time) t = user_time[0:4] + user_start_time + (0, ) + user_time[6:9] # for i in range(9): # t[i] = user_time[i] # # t[4] = user_start_time # t[5] = 0 # print(t) delay_time = time.mktime(t) start_time = int(delay_time - local_time) # print('Waiting to start...') # Set start time, where start_time > 2.0 self.uhd_usrp_source_0.set_start_time(uhd.time_spec(start_time)) # Delay start time # Set to one radio next pps, initially self.uhd_usrp_source_0.set_time_unknown_pps(uhd.time_spec(0.0)) curr_hw_time = self.uhd_usrp_source_0.get_time_last_pps() while curr_hw_time == self.uhd_usrp_source_0.get_time_last_pps(): pass # Sleep for 50ms time.sleep(0.05) # Synchronize both radios time registers self.uhd_usrp_source_0.set_time_next_pps(uhd.time_spec_t(0.0)) # Sleep for a couple seconds to make sure all usrp time registers latched and settled time.sleep(2) # Check the last pps time for ii in range(0, 5): last_pps0 = self.uhd_usrp_source_0.get_time_last_pps() print("last_pps0 : %6.12f" % uhd.time_spec_t.get_real_secs(last_pps0)) time.sleep(1.0) print('Cute cuddly Kittens') print(time.ctime())
def start_tdma_net(self, start_time, burst_duration, idle_duration): # specify the tdma pulse parameters and connect the # pulse source to usrp sinker also specify the usrp source # with the specified start time self.pulse_srcs = [] n_devices = len(self.transmitters) if (n_devices > 0): time_slot = (burst_duration + idle_duration)/NETWORK_SIZE #print 'base_s_time = %.7f' %start_time for i in range(n_devices): s_time = uhd.time_spec_t(start_time + time_slot*(NODES_PC*self._node_id + i)) #print 'specified_time = %.7f' %s_time.get_real_secs() local_time = self.transmitters[i].u.get_time_now().get_real_secs() print 'current time 1 = %.7f' %local_time self.pulse_srcs.append(uhd.pulse_source(s_time.get_full_secs(), s_time.get_frac_secs(), self._sample_rate, idle_duration, burst_duration, 1)) # Connect the pulse source to the transmitters self.transmitters[i].insert_tdma_throttle(self.pulse_srcs[i]) self.connect(self.txpaths[i], self.transmitters[i]) # Set the start time for sensors self.sensors[i].u.set_start_time(uhd.time_spec_t(start_time)) else: exit("no devices on this node!") # start the flow graph and all the sensors self.start() time.sleep(5) for i in range(n_devices): current_time = self.sensors[i].u.get_time_now().get_real_secs() print "current time 2 = %.7f" %current_time #print "base_s_time = %.7f" %start_time self.sensors[i].u.start() #start the transmitting of data packets self.tx_srcs[i].start()
def start(self): try: self.uhd_dev = eval("self.parent.%s" % (self.device_name)) sensor_names = self.uhd_dev.get_mboard_sensor_names() except: self.uhd_dev = None gr.log.warn("UHD Device not found, re-check the block config") return False if 'gps_locked' in sensor_names: if not self.uhd_dev.get_mboard_sensor('gps_locked').to_bool(): gr.log.warn("Can't set GPS time, no fix") return True self.uhd_dev.set_time_source('gpsdo') last = self.uhd_dev.get_time_last_pps() next = self.uhd_dev.get_time_last_pps() while last == next: time.sleep(0.05) next = self.uhd_dev.get_time_last_pps() time.sleep(0.1) self.uhd_dev.set_time_next_pps( uhd.time_spec_t( self.uhd_dev.get_mboard_sensor('gps_time').to_int() + 1)) time.sleep(1.1) self.has_gps_sensor = True self.timer.start() else: gr.log.info("No GPSDO found using OS time") self.uhd_dev.set_time_next_pps( uhd.time_spec_t(int(time.time()) + 1)) self.has_gps_sensor = False return True
def timing(self): # Get user time print('Type in desired start time (min only)') user_start_time = (int(input()), ) # Convert local time to sturct_time format local_time = time.time() user_time = time.localtime(local_time) # Create future time in struct_time format t = user_time[0:4] + user_start_time + (0, ) + user_time[6:9] # Convert future time to seconds future_time = time.mktime(t) # Set start time delay to time difference between future and local time start_time = int(future_time - local_time) # Set start time, where start_time > 2.0 self.uhd_usrp_source_0.set_start_time(uhd.time_spec(start_time)) # Set to one radio next pps, initially self.uhd_usrp_source_0.set_time_unknown_pps(uhd.time_spec(0.0)) curr_hw_time = self.uhd_usrp_source_0.get_time_last_pps() while curr_hw_time == self.uhd_usrp_source_0.get_time_last_pps(): pass # Sleep for 50ms time.sleep(0.05) # Synchronize both radios time registers self.uhd_usrp_source_0.set_time_next_pps(uhd.time_spec_t(0.0)) # Sleep for a couple seconds to make sure all usrp time registers latched and settled time.sleep(2) # Check the last pps time for ii in range(0, 5): last_pps0 = self.uhd_usrp_source_0.get_time_last_pps() print("last_pps0 : %6.12f" % uhd.time_spec_t.get_real_secs(last_pps0)) time.sleep(1.0) # For completion varification print('Cute cuddly Kittens') print(time.ctime())
def init_usrp(self, mboard, ip_address, clock_rate, sampling_rate, number_of_channels, internal_clock): """Setup the USRP""" self._channels_id_list = range(number_of_channels) # Init USRP: See http://gnuradio.org/doc/doxygen/page_uhd.html self._usrp = uhd.usrp_sink( device_addr='addr={:s},master_clock_rate={:f}'.format( ip_address, clock_rate), stream_args=uhd.stream_args( cpu_format="fc32", otw_format="sc16", channels=self._channels_id_list, )) if not internal_clock: # Try to set an external clock source if available try: print('Try external clock.') self._usrp.set_clock_source('external', mboard=mboard) except RuntimeError as e: print(e) print( 'Could not lock to external clock source. Lock back to internal clock source.' ) self._usrp.set_clock_source('internal', mboard=mboard) while not self._usrp.get_mboard_sensor("ref_locked", mboard).to_bool(): print('Wait for ref_locked') time.sleep(1) self._usrp.set_time_unknown_pps(uhd.time_spec_t(0.0)) time.sleep(2.0) # Wait for clocks to settle print('Time setup finished: {:f}, {:f}'.format( self._usrp.get_time_now(mboard=mboard).get_real_secs(), self._usrp.get_time_last_pps(mboard=mboard).get_real_secs())) self._usrp.set_samp_rate(sampling_rate) self._usrp.set_subdev_spec('A:0 B:0', mboard=mboard) print('USRP initialized:') print('- Configured clock rate: {:f}'.format( self._usrp.get_clock_rate())) print('- Configured clock source: {:s}'.format( self._usrp.get_clock_source(mboard=mboard))) print('- Configured sampling rate: {:f}'.format( self._usrp.get_samp_rate()))
def tx_frames(self): #print self.msg_from_app toatal_byte_count=0 frame_count=0 print "tx_frames" #control the uhd self.usrp_sink.set_center_freq(self.freq_list[self.hop_index]) self.usrp_sink.clear_command_time() self.usrp_sink.set_command_time(uhd.time_spec_t(self.antenna_start)) #print self.antenna_start,self.usrp_sink.get_time_now().get_real_secs() self.current_hid=self.hop_index print "Hopping to : ",self.usrp_sink.get_center_freq() #put residue from previous execution if self.has_old_msg: toatal_byte_count+=len(self.old_msg)+self.overhead self.tx_queue.put(self.old_msg) frame_count+=1 self.has_old_msg=False #print 'old Msg' #fill outgoing queue until empty or maximum byter queued for slot while(not self.q.empty()): msg=self.q.get() toatal_byte_count+=len(msg)+self.overhead if(toatal_byte_count>=self.bytes_per_slot): self.has_old_msg=True self.old_msg=msg #print 'residue' break else: self.has_old_msg=False self.tx_queue.put(msg) frame_count+=1 #print frame_count while frame_count: msg=self.tx_queue.get() #print "sending" self.send_pkt_phy(msg,self.pkt_count,DATA_PKT) self.pkt_count=(self.pkt_count+1)%256 frame_count-=1
def crimson_source_c(channels, sample_rate, center_freq, gain): """ Connects to the crimson and returns a complex source object. """ usrp_source = uhd.usrp_source( "crimson", uhd.stream_args(cpu_format="fc32", otw_format="sc16", channels=channels), False) usrp_source.set_samp_rate(sample_rate) usrp_source.set_clock_source("internal") for channel in channels: usrp_source.set_center_freq(center_freq, channel) usrp_source.set_gain(gain, channel) usrp_source.set_time_now(uhd.time_spec_t(0.0)) return usrp_source
def tune_front_ends(self, center_frequency, no_dsp_offset=False, mboard=0): """Tune the front-ends""" assert (self._usrp is not None and self._channels_id_list is not None) # When was last PPS observed? last_pps_time_seconds = self._usrp.get_time_last_pps( mboard).get_real_secs() print('Pre-tune: last PPS {:f}'.format(last_pps_time_seconds)) future_cmd_time = uhd.time_spec_t(last_pps_time_seconds + 2.0) # Make sure the next commands are executed at future_cmd_time self._usrp.set_command_time(future_cmd_time, mboard) for channel_id in self._channels_id_list: # Can simply be: self._usrp.set_center_freq (2655e6) if no_dsp_offset: dsp_offset = 0 else: dsp_offset = self._usrp.get_samp_rate( ) # To get any leakage from the receive LO out of the way print('DSP offset:', dsp_offset) tune_result = self._usrp.set_center_freq( uhd.tune_request(target_freq=center_frequency, rf_freq_policy=uhd.tune_request.POLICY_MANUAL, rf_freq=center_frequency - dsp_offset, dsp_freq_policy=uhd.tune_request.POLICY_AUTO), channel_id) if tune_result is None: print('Could not set center frequency.') sys.exit(-1) # We're done self._usrp.clear_command_time(mboard) print('Post-tune: last PPS {:f}'.format( self._usrp.get_time_last_pps(mboard).get_real_secs())) time.sleep(3.0) # Wait for commands to have executed for channel_id in self._channels_id_list: print( 'Front-end/channel {:d}: Setting center frequency was successful.' .format(channel_id)) print(tune_result.actual_rf_freq, tune_result.actual_dsp_freq) print('Frequency set to: {:f}'.format( self._usrp.get_center_freq(chan=channel_id)))
def crimson_sink_s(channels, sample_rate, center_freq, gain): """ Connects to the crimson and returns a sink object expecting interleaved shorts of complex data. """ usrp_sink = uhd.usrp_sink( "crimson", uhd.stream_args(cpu_format="sc16", otw_format="sc16", channels=channels)) usrp_sink.set_samp_rate(sample_rate) usrp_sink.set_clock_source("internal") for channel in channels: usrp_sink.set_center_freq(center_freq, channel) usrp_sink.set_gain(gain, channel) usrp_sink.set_time_now(uhd.time_spec_t(0.0)) return usrp_sink
def set_dev_time(usrp): # 7) Verify that usrp->get_time_last_pps() and usrp->get_mboard_sensor("gps_time") return the same time. # while usrp.get_time_last_pps().get_real_secs() + 1 != usrp.get_mboard_sensor("gps_time").to_real(): while usrp.get_time_last_pps().get_real_secs() != usrp.get_mboard_sensor( "gps_time").to_real(): print(usrp.get_time_last_pps().get_real_secs()) print(usrp.get_mboard_sensor("gps_time").to_real()) # 1) Poll on usrp->get_mboard_sensor("gps_locked") until it returns true while not usrp.get_mboard_sensor("gps_locked", 0).to_bool(): print("Waiting for gps lock...") time.sleep(5) print("...GPS locked!") # 2) Poll on usrp->get_time_last_pps() until a change is seen. pps = usrp.get_time_last_pps() while usrp.get_time_last_pps() == pps: time.sleep(0.1) # 3) Sleep 200ms (allow NMEA string to propagate) time.sleep(0.2) # 4) Use "usrp->set_time_next_pps(uhd::time_spec_t(usrp->get_mboard_sensor("gps_time").to_int()+1));" to set the time usrp.set_time_next_pps( uhd.time_spec_t(usrp.get_mboard_sensor("gps_time").to_int() + 2)) # 5) Poll on usrp->get_time_last_pps() until a change is seen. pps = usrp.get_time_last_pps() while usrp.get_time_last_pps() == pps: time.sleep(0.1) # 6) Sleep 200ms (allow NMEA string to propagate) time.sleep(0.2) print('USRP last PPS = %i, GPSDO = %i' % (\ usrp.get_time_last_pps().get_real_secs(), usrp.get_mboard_sensor("gps_time").to_real() )) print('time set')
def synchronize(self): if (self.usrp_source_object == None) or (self.has_gpsdo == False): return False # check if gps is locked locked = self.usrp_source_object.get_mboard_sensor( "gps_locked").to_bool() # only set time if changing from unlocked to locked if (self.gps_locked) and (locked): # no change in lock status self.gps_locked = locked return True elif (self.gps_locked) and (not locked): # system became unlocked - do nothing self.gps_locked = locked return True elif (not self.gps_locked) and (not locked): # system remains unlocked self.gps_locked = locked return True else: # system has gone from unlocked to locked self.gps_locked = locked pass # stop first self.usrp_source_object.stop() self.log.debug("USRP Object Stopped for Time Synchronization") # TODO: Find way to ensure we poll as closely to the second boundary as # possible to ensure we get as accurate a reading as possible #gps_time = self.usrp_source_object.get_mboard_sensor("gps_time") ## check PPS and compare UHD device time to GPS time ## we only care about the full seconds for now #gps_time = self.usrp_source_object.get_mboard_sensor("gps_time") #print "gps_time = " + repr(gps_time) #last_pps_time = self.usrp_source_object.get_time_last_pps() #print "last_pps_time = " + repr(last_pps_time) # we only care about the full seconds gps_seconds = self.usrp_source_object.get_mboard_sensor( "gps_time").to_int() self.log.debug("gps_seconds = " + repr(gps_seconds)) pps_seconds = self.usrp_source_object.get_time_last_pps().to_ticks(1.0) self.log.debug("pps_seconds = " + repr(pps_seconds)) if (pps_seconds != gps_seconds): self.log.debug("Trying to align the device time to GPS time...") try: self.usrp_source_object.set_time_next_pps( uhd.time_spec_t(gps_seconds + 1)) except Exception as e: self.log.error("Set Time Next PPS Error: " + repr(e)) # allow some time to make sure the PPS has come time.sleep(1.1) # check again gps_seconds = self.usrp_source_object.get_mboard_sensor( "gps_time").to_int() self.log.debug("updated gps_time = " + repr(gps_seconds)) pps_seconds = self.usrp_source_object.get_time_last_pps().to_ticks( 1.0) self.log.debug("updated last_pps_time = " + repr(pps_seconds)) if (pps_seconds == gps_seconds): self.log.debug("Successful USRP GPS Time Synchronization") else: self.log.debug("Unable to synchronize GPS time") # set start time in future self.usrp_source_object.set_start_time( uhd.time_spec_t(gps_seconds + 2.0)) # restart self.usrp_source_object.start() self.log.debug("USRP Objected Restarted After Time Synchronization") return True
cpu_format="fc32", args='', channels=list(range(0, 2)), ), ) #streamer restart/align stop_cmd = uhd.stream_cmd_t(uhd.stream_cmd_t.STREAM_MODE_STOP_CONTINUOUS) stop_cmd.stream_now = True self.uhd_usrp_source_0.issue_stream_cmd(stop_cmd) stream_cmd = uhd.stream_cmd_t(uhd.stream_cmd_t.STREAM_MODE_START_CONTINUOUS) stream_cmd.stream_now = False #delay by 5s stream_cmd.time_spec = self.uhd_usrp_source_0.get_time_now() + uhd.time_spec_t( 5.0) self.uhd_usrp_source_0.issue_stream_cmd(stream_cmd) #freq align - potential phase sync retune_time = self.uhd_usrp_source_0.get_time_now() + uhd.time_spec_t(5.0) self.uhd_usrp_source_0.set_command_time(retune_time) center_freq_tmp = 2.4501e9 tune_req = uhd.tune_request_t(center_freq_tmp) self.uhd_usrp_source_0.set_center_freq(tune_req, 0) self.uhd_usrp_source_0.set_center_freq(tune_req, 1) self.uhd_usrp_source_0.clear_command_time() print("Finished!") # %%
def process_payload(self, payload, options): #print 'process_pay_load' length = len(payload) #test code #if length == 12: # time.sleep(0.008) # self.round_data_collect(0, 1) if length <= 17: print 'useless payload' return 1 (pktno, pktsize, fromaddr, toaddr, pkttype) = struct.unpack('!IHIIB', payload[0:15]) if length != pktsize: print 'invalid payload' return 1 ####State Machine For the Cluster Head if self.node_type == "head": if pkttype == DATA_TYPE: rt = self.tb.source.u.get_time_now().get_real_secs() print 'recieve the data at time %.7f' %rt (node_id,) = struct.unpack('!H', payload[15:17]) if self.state == SENSE_START: if node_id == 0 and self.current_rep_id == -1: #Got data from the 1st node #print "incoming_payload =", pkt_utils.string_to_hex_list(payload) rt = self.defragment(payload, node_id) if rt == 0: #Need next packet from the same node return 0 elif rt == 1: #Completed collection of all the framgmented packets self.state = ROUND_COLLECTING elif rt > 1 or rt < 0: #Errors # need to add code to reset all the nodes self.state = HEAD_IDLE return 1 else: print 'incorrect incoming data from node ', node_id # Could broadcast the reset command to reset all the nodes self.state = HEAD_IDLE return 1 elif self.state == ROUND_COLLECTING: if node_id == self.current_rep_id: #print "incoming_payload =", pkt_utils.string_to_hex_list(payload) rt = self.defragment(payload, node_id) if rt == 0: #Need next packet from the same node return 0 elif rt > 1 or rt < 0: #Need to add code for reset the nodes self.state = HEAD_IDLE return 1 #Completed collection of all the fragemented packets if self.current_rep_id >= self.net_size - 1: print "last node has reported data" finish_time = self.tb.sensor.u.get_time_now().get_real_secs() print '***************************************This round of collection started at time %.7f' %(self.current_start_time - 0.09) print '==============================This round collection finished at time %.7f' %finish_time self.state = ROUND_COLLECTED self.current_rep_id = -1 self.current_loop += 1 if self.current_loop < self.loop_number: print 'initiate the next round of sensing' #time.sleep(0.01) self.start_sensing(options.samp_num) self.state = SENSE_START return 0 else: self.current_loop = 0 print 'Complete all rounds of sesning' if self.process_collected_data() == 1: print 'All round of sensing data are processed' self.state = HEAD_IDLE else: print 'Data error' else: print 'incorrect incoming data from node ', node_id self.state = HEAD_IDLE return 1 else: print 'Should not receive data in the current state' self.state = HEAD_IDLE return 1 # If reach here, the state should be ROUND_COLLECTING if self.state == ROUND_COLLECTING: (tran_id,) = struct.unpack('!d', payload[17:25]) # use start time as transaction ID # Collect the data from the next node t = self.tb.sensor.u.get_time_now().get_real_secs() print '------------------------------------------collect next node at time ', t self.current_rep_id = node_id + 1 if self.current_rep_id < self.net_size: time.sleep(0.009) #Maybe here the delay can be ignored as the last node don't need to receive it. self.round_data_collect(tran_id, self.current_rep_id) else: # should not reach here print 'error in report node id' return 1 ####State machine for the CLuster Node: elif self.node_type == "node": rt = self.tb.sensors[0].u.get_time_now().get_real_secs() print 'recieve the commnad at time %.7f' %rt #print "incoming_command =", pkt_utils.string_to_hex_list(payload) if pkttype == CTRL_TYPE: (ctrl_cmd,) = struct.unpack('!B', payload[15:16]) print 'pkttype == CTRL_TYPE' if self.state == NODE_IDLE: print '-->NODE_IDLE' if ctrl_cmd == START_SENSE: # start sensing received print 'START_SENSE received' self.state = SENSING print '----->SENSING' (start_time, samp_num) = struct.unpack('!dH', payload[16:26]) self.current_start_time = start_time print "self.current_start_time = ", pkt_utils.string_to_hex_list(payload[16:24]) self.current_samp_num = samp_num print 'samp_num = ', samp_num print 'start_time = %.7f' %(start_time + 0.7) # start the data collection as specified time #sensor_time = self.sensor.u.get_time_now().get_real_secs() #print 'sensor_time = %.7f' %sensor_time #if start_time + 0.015 - sensor_time > 0: for i in range(len(self.sensors)): self.sensors[i].u.set_start_time(uhd.time_spec_t(start_time+0.70)) #started later 0.070s # Start data collecting if (STREAM_OR_FINITE == 1): #finite acqusition samp_num = int(10*options.sx_samprate) current_t = self.sensor.u.get_time_now().get_real_secs() print 'current time = %.7f' %current_t self.samps = self.sensor.u.finite_acquisition(samp_num) if len(self.samps) == 0: print 'no samps captured' self.state = NODE_IDLE return 0 elif (STREAM_OR_FINITE == 0): #streaming data collection #start streaming here for i in range(len(self.sensors)): self.sensors[i].u.start() #start the timer self.sense_timer = threading.Timer(STREAM_TIME, self.stop_sensing) self.sense_timer.start() self.state = SENSING return 0 # the data report will be done in timer expiring callback #o_samps = np.array(np.real(self.samps[int(0.5*options.sx_samprate):])) #o_samps.astype('float64').tofile(self.fd) #print 'samps len = ', len(self.samps) #compute the covariance matrix #mat = [] #l_v = 64 #for i in range(len(self.samps) - l_v + 1): # v = [] # for j in range(l_v): # v.append(abs(self.samps[i + j])) # mat.append(v) #matx = np.array(mat).T #covmat = np.cov(matx) #trace_cov = np.trace(covmat) #print 'trace is ', trace_cov if self.node_id == 0: # for node 0, just report the data to head print 'begin reporting data, data per pkt = ', options.data_pkt #time.sleep(0.01) #Don't need to delay due to the sensing time plus the sensing delay there #test code #self.send_test_data() #return 0 if self.report_data(self.samps, self.node_id, samp_num, options.data_pkt) == 1: print 'error in reporting data' return 1 self.state = NODE_IDLE print '------>NODE_IDLE' else: self.state = WAIT_REPORT print '------>WAIT_REPORT' else: print 'Recieved incorrect cmd in NODE_IDLE state' return 1 elif self.state == WAIT_REPORT: print '---->WAIT_REPORT' if ctrl_cmd == COLLECT_DATA: print 'COLLECT_DATA received' (node_id, ) = struct.unpack('!H', payload[16:18]) if node_id == self.node_id: print 'begin reporting data, data per pkt = ', options.data_pkt #time.sleep(0.004) #Here we need a delay to ensure the cluster head switched to receiving #test code #self.send_test_data() #return 0 self.report_data(self.samps, self.node_id, self.current_samp_num, options.data_pkt) self.state = NODE_IDLE else: print 'Received incorrect cmd in WAIT_REPORT state' elif self.state == SENSING: #only reset command accepted, not added yet print 'Only Reset command accepted at this state, not implemented' else: print "error node type" return 0
def __init__(self): test_grc.__init__(self) self.uhd_usrp_sink_0.set_time_now(uhd.time_spec_t(0.0))
def __init__(self, IPAddress): ################################################## # Blocks ################################################## self.uhd_usrp_sink_0 = uhd.usrp_sink( " ,".join((IPAddress, "")), uhd.stream_args( cpu_format="fc32", channels=range(1), ), ) self.uhd_usrp_sink_0.set_clock_source("external", 0) self.uhd_usrp_sink_0.set_samp_rate(32000) self.uhd_usrp_sink_0.set_center_freq(915e6, 0) self.uhd_usrp_sink_0.set_gain(0, 0) self.uhd_usrp_sink_0.set_antenna("TX/RX", 0) #self.analog_sig_source_x_0 = analog.sig_source_c(samp_rate, analog.GR_COS_WAVE, 1000, 1, 0) ################################################## # Adding line for time sync purpose ################################################## try: client = ntplib.NTPClient() response = client.request('pool.ntp.org') os.system('date ' + time.strftime( '%m%d%H%M%Y.%S', time.localtime(response.tx_time))) #os.system(time.strftime('%m%d%H%M%Y.%S',time.localtime(response.tx_time))) system_time_min = int(time.strftime('%M')) system_time_min = (system_time_min * 60) #print (system_time_min) system_time_sec = int(time.strftime('%S')) #print (system_time_sec) system_time_str = (system_time_min + system_time_sec) #print(system_time_str) system_time = int(system_time_str) print(system_time) except: print('Could not sync with time server.') print('Done.') #time.sleep(2.0) #self.uhd_usrp_source_0.set_time_unknown_pps(uhd.time_spec(0.0)) #self.uhd_usrp_source_0.set_time_next_pps(system_time) #self.uhd_usrp_source_0.set_time_now(uhd.time_spec(system_time)) self.uhd_usrp_sink_0.set_time_next_pps(uhd.time_spec_t(system_time + 1)) ################################################## end1 = time.time() print "radio instantiation time is ", end1 - start1, " seconds" ################################################## # Getting usrp time ################################################## for ii in range(0, 5): #last_time = self.uhd_usrp_source_0.get_time_now() last_pps0 = self.uhd_usrp_sink_0.get_time_last_pps() #print "last_time : %6.12f\n"%uhd.time_spec_t.get_real_secs(last_time) print "last_time_0 : %6.12f\n" % uhd.time_spec_t.get_real_secs( last_pps0) #print "last_pps0 : %6.12f\n"%uhd.time_spec_t.get_real_secs(last_pps0) time.sleep(1.0)
def __init__(self): gr.top_block.__init__(self, "Calibration Example") Qt.QWidget.__init__(self) self.setWindowTitle("Calibration Example") try: self.setWindowIcon(Qt.QIcon.fromTheme("gnuradio-grc")) except: pass self.top_scroll_layout = Qt.QVBoxLayout() self.setLayout(self.top_scroll_layout) self.top_scroll = Qt.QScrollArea() self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame) self.top_scroll_layout.addWidget(self.top_scroll) self.top_scroll.setWidgetResizable(True) self.top_widget = Qt.QWidget() self.top_scroll.setWidget(self.top_widget) self.top_layout = Qt.QVBoxLayout(self.top_widget) self.top_grid_layout = Qt.QGridLayout() self.top_layout.addLayout(self.top_grid_layout) self.settings = Qt.QSettings("GNU Radio", "calibration_example_gui_2x") self.restoreGeometry(self.settings.value("geometry").toByteArray()) ################################################## # Variables ################################################## self.speed_of_light = speed_of_light = 299792458 self.antenna_spacing = antenna_spacing = 0.1 self.samp_rate = samp_rate = 100000000 / 64 self.gain_rx = gain_rx = 0 self.center_freq = center_freq = speed_of_light / (2 * antenna_spacing) self.cal_freq = cal_freq = 1024 ################################################## # Blocks ################################################## self.uhd_usrp_source_0_0_0 = uhd.usrp_source( ",".join(("addr0=192.168.70.2,addr1=192.168.20.2,addr2=192.168.30.2,addr3=192.168.50.2", "")), uhd.stream_args(cpu_format="fc32", channels=range(4)), ) self.uhd_usrp_source_0_0_0.set_clock_source("external", 0) self.uhd_usrp_source_0_0_0.set_time_source("external", 0) self.uhd_usrp_source_0_0_0.set_clock_source("external", 1) self.uhd_usrp_source_0_0_0.set_time_source("external", 1) self.uhd_usrp_source_0_0_0.set_clock_source("external", 2) self.uhd_usrp_source_0_0_0.set_time_source("external", 2) self.uhd_usrp_source_0_0_0.set_clock_source("external", 3) self.uhd_usrp_source_0_0_0.set_time_source("external", 3) self.uhd_usrp_source_0_0_0.set_time_unknown_pps(uhd.time_spec()) self.uhd_usrp_source_0_0_0.set_samp_rate(samp_rate) # Tell boards to run these commands at this specific time in the future cmd_time = self.uhd_usrp_source_0_0_0.get_time_now() + uhd.time_spec_t(1.0) s1 = 0 s2 = 5 s3 = 700 s4 = 640 cmd_time1 = cmd_time + uhd.time_spec_t(0) cmd_time2 = cmd_time + uhd.time_spec_t(s2 / samp_rate) cmd_time3 = cmd_time + uhd.time_spec_t(s3 / samp_rate) cmd_time4 = cmd_time + uhd.time_spec_t(s4 / samp_rate) self.uhd_usrp_source_0_0_0.set_command_time(cmd_time1, 0) self.uhd_usrp_source_0_0_0.set_command_time(cmd_time2, 1) self.uhd_usrp_source_0_0_0.set_command_time(cmd_time3, 2) self.uhd_usrp_source_0_0_0.set_command_time(cmd_time4, 3) self.uhd_usrp_source_0_0_0.set_center_freq(center_freq, 0) self.uhd_usrp_source_0_0_0.set_gain(gain_rx, 0) self.uhd_usrp_source_0_0_0.set_center_freq(center_freq, 1) self.uhd_usrp_source_0_0_0.set_gain(gain_rx, 1) self.uhd_usrp_source_0_0_0.set_center_freq(center_freq, 2) self.uhd_usrp_source_0_0_0.set_gain(gain_rx, 2) self.uhd_usrp_source_0_0_0.set_center_freq(center_freq, 3) self.uhd_usrp_source_0_0_0.set_gain(gain_rx, 3) self.uhd_usrp_source_0_0_0.clear_command_time() time.sleep(1.5) self.uhd_usrp_sink_0_0 = uhd.usrp_sink( ",".join(("addr=192.168.40.2", "")), uhd.stream_args(cpu_format="fc32", channels=range(1)) ) self.uhd_usrp_sink_0_0.set_clock_source("mimo", 0) self.uhd_usrp_sink_0_0.set_time_source("mimo", 0) self.uhd_usrp_sink_0_0.set_samp_rate(samp_rate) self.uhd_usrp_sink_0_0.set_center_freq(center_freq, 0) self.uhd_usrp_sink_0_0.set_gain(10, 0) self.qtgui_time_sink_x_0 = qtgui.time_sink_f( 1526 * 2, samp_rate, "", 4 # size # samp_rate # name # number of inputs ) self.qtgui_time_sink_x_0.set_update_time(0.10) self.qtgui_time_sink_x_0.set_y_axis(-1, 1) self.qtgui_time_sink_x_0.set_y_label("Amplitude", "") self.qtgui_time_sink_x_0.enable_tags(-1, True) self.qtgui_time_sink_x_0.set_trigger_mode(qtgui.TRIG_MODE_AUTO, qtgui.TRIG_SLOPE_POS, 0.0, 0, 0, "") self.qtgui_time_sink_x_0.enable_autoscale(True) self.qtgui_time_sink_x_0.enable_grid(False) self.qtgui_time_sink_x_0.enable_control_panel(True) if not True: self.qtgui_time_sink_x_0.disable_legend() labels = ["", "", "", "", "", "", "", "", "", ""] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = ["blue", "red", "green", "black", "cyan", "magenta", "yellow", "dark red", "dark green", "blue"] styles = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] markers = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] for i in xrange(4): if len(labels[i]) == 0: self.qtgui_time_sink_x_0.set_line_label(i, "Data {0}".format(i)) else: self.qtgui_time_sink_x_0.set_line_label(i, labels[i]) self.qtgui_time_sink_x_0.set_line_width(i, widths[i]) self.qtgui_time_sink_x_0.set_line_color(i, colors[i]) self.qtgui_time_sink_x_0.set_line_style(i, styles[i]) self.qtgui_time_sink_x_0.set_line_marker(i, markers[i]) self.qtgui_time_sink_x_0.set_line_alpha(i, alphas[i]) self._qtgui_time_sink_x_0_win = sip.wrapinstance(self.qtgui_time_sink_x_0.pyqwidget(), Qt.QWidget) self.top_layout.addWidget(self._qtgui_time_sink_x_0_win) self.blocks_complex_to_real_1_0 = blocks.complex_to_real(1) self.blocks_complex_to_real_1 = blocks.complex_to_real(1) self.blocks_complex_to_real_0_0 = blocks.complex_to_real(1) self.blocks_complex_to_real_0 = blocks.complex_to_real(1) self.analog_sig_source_x_0 = analog.sig_source_c(samp_rate, analog.GR_COS_WAVE, cal_freq, 1, 0) ################################################## # Connections ################################################## self.connect((self.analog_sig_source_x_0, 0), (self.uhd_usrp_sink_0_0, 0)) self.connect((self.blocks_complex_to_real_0, 0), (self.qtgui_time_sink_x_0, 0)) self.connect((self.blocks_complex_to_real_0_0, 0), (self.qtgui_time_sink_x_0, 2)) self.connect((self.blocks_complex_to_real_1, 0), (self.qtgui_time_sink_x_0, 1)) self.connect((self.blocks_complex_to_real_1_0, 0), (self.qtgui_time_sink_x_0, 3)) self.connect((self.uhd_usrp_source_0_0_0, 0), (self.blocks_complex_to_real_0, 0)) self.connect((self.uhd_usrp_source_0_0_0, 2), (self.blocks_complex_to_real_0_0, 0)) self.connect((self.uhd_usrp_source_0_0_0, 1), (self.blocks_complex_to_real_1, 0)) self.connect((self.uhd_usrp_source_0_0_0, 3), (self.blocks_complex_to_real_1_0, 0))
def start(self): ''' Overload start function ''' try: # Check to ensure self.usrp_source_object = eval("self.parent.%s" % self.usrp_source) except AttributeError: print "Unable to acquire usrp object for synchronization" return True # stop first self.usrp_source_object.stop() print "USRP Object Stopped for Time Synchronization" # TODO: Find way to ensure we poll as closely to the second boundary as # possible to ensure we get as accurate a reading as possible #gps_time = self.usrp_source_object.get_mboard_sensor("gps_time") ## check PPS and compare UHD device time to GPS time ## we only care about the full seconds for now #gps_time = self.usrp_source_object.get_mboard_sensor("gps_time") #print "gps_time = " + repr(gps_time) #last_pps_time = self.usrp_source_object.get_time_last_pps() #print "last_pps_time = " + repr(last_pps_time) # we only care about the full seconds gps_seconds = self.usrp_source_object.get_mboard_sensor( "gps_time").to_int() print "gps_seconds = " + repr(gps_seconds) pps_seconds = self.usrp_source_object.get_time_last_pps().to_ticks(1.0) print "pps_seconds = " + repr(pps_seconds) if (pps_seconds != gps_seconds): print "\nTrying to align the device time to GPS time..." try: self.usrp_source_object.set_time_next_pps( uhd.time_spec_t(gps_seconds + 1)) except Exception as e: print "Set Time Next PPS Error: " + repr(e) # allow some time to make sure the PPS has come time.sleep(1.1) # check again gps_seconds = self.usrp_source_object.get_mboard_sensor( "gps_time").to_int() print "updated gps_time = " + repr(gps_seconds) pps_seconds = self.usrp_source_object.get_time_last_pps().to_ticks( 1.0) print "updated last_pps_time = " + repr(pps_seconds) if (pps_seconds == gps_seconds): print "Successful USRP GPS Time Synchronization" else: print "Unable to synchronize GPS time" # set start time in future self.usrp_source_object.set_start_time( uhd.time_spec_t(gps_seconds + 2.0)) # restart self.usrp_source_object.start() print "USRP Objected Restarted After Time Synchronization" return True
def start_streaming(self): stime = self.source.u.get_time_now().get_real_secs() self.source.u.set_start_time(uhd.time_spec_t(stime + 2)) #self.start() self.source.u.start() print 'start streaming'
def __init__(self): gr.top_block.__init__(self, "Calibration Example") Qt.QWidget.__init__(self) self.setWindowTitle("Calibration Example") try: self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc')) except: pass self.top_scroll_layout = Qt.QVBoxLayout() self.setLayout(self.top_scroll_layout) self.top_scroll = Qt.QScrollArea() self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame) self.top_scroll_layout.addWidget(self.top_scroll) self.top_scroll.setWidgetResizable(True) self.top_widget = Qt.QWidget() self.top_scroll.setWidget(self.top_widget) self.top_layout = Qt.QVBoxLayout(self.top_widget) self.top_grid_layout = Qt.QGridLayout() self.top_layout.addLayout(self.top_grid_layout) self.settings = Qt.QSettings("GNU Radio", "calibration_example_gui_2x_measure") self.restoreGeometry(self.settings.value("geometry").toByteArray()) ################################################## # Variables ################################################## self.speed_of_light = speed_of_light = 299792458 self.antenna_spacing = antenna_spacing = 0.1 self.variable_qtgui_chooser_0_1_0 = variable_qtgui_chooser_0_1_0 = 0 self.variable_qtgui_chooser_0_0 = variable_qtgui_chooser_0_0 = 1 self.samp_rate = samp_rate = 100000000/64 self.gain_rx = gain_rx = 0 self.center_freq = center_freq = speed_of_light/(2*antenna_spacing) self.cal_freq = cal_freq = 1024 ################################################## # Blocks ################################################## self._variable_qtgui_chooser_0_1_0_options = (1, 0, ) self._variable_qtgui_chooser_0_1_0_labels = ("Stop", "Running", ) self._variable_qtgui_chooser_0_1_0_group_box = Qt.QGroupBox("Sync System") self._variable_qtgui_chooser_0_1_0_box = Qt.QHBoxLayout() class variable_chooser_button_group(Qt.QButtonGroup): def __init__(self, parent=None): Qt.QButtonGroup.__init__(self, parent) @pyqtSlot(int) def updateButtonChecked(self, button_id): self.button(button_id).setChecked(True) self._variable_qtgui_chooser_0_1_0_button_group = variable_chooser_button_group() self._variable_qtgui_chooser_0_1_0_group_box.setLayout(self._variable_qtgui_chooser_0_1_0_box) for i, label in enumerate(self._variable_qtgui_chooser_0_1_0_labels): radio_button = Qt.QRadioButton(label) self._variable_qtgui_chooser_0_1_0_box.addWidget(radio_button) self._variable_qtgui_chooser_0_1_0_button_group.addButton(radio_button, i) self._variable_qtgui_chooser_0_1_0_callback = lambda i: Qt.QMetaObject.invokeMethod(self._variable_qtgui_chooser_0_1_0_button_group, "updateButtonChecked", Qt.Q_ARG("int", self._variable_qtgui_chooser_0_1_0_options.index(i))) self._variable_qtgui_chooser_0_1_0_callback(self.variable_qtgui_chooser_0_1_0) self._variable_qtgui_chooser_0_1_0_button_group.buttonClicked[int].connect( lambda i: self.set_variable_qtgui_chooser_0_1_0(self._variable_qtgui_chooser_0_1_0_options[i])) self.top_layout.addWidget(self._variable_qtgui_chooser_0_1_0_group_box) self._variable_qtgui_chooser_0_0_options = (0, 1, ) self._variable_qtgui_chooser_0_0_labels = ("Enable", "Disable", ) self._variable_qtgui_chooser_0_0_group_box = Qt.QGroupBox("Source Enable") self._variable_qtgui_chooser_0_0_box = Qt.QVBoxLayout() class variable_chooser_button_group(Qt.QButtonGroup): def __init__(self, parent=None): Qt.QButtonGroup.__init__(self, parent) @pyqtSlot(int) def updateButtonChecked(self, button_id): self.button(button_id).setChecked(True) self._variable_qtgui_chooser_0_0_button_group = variable_chooser_button_group() self._variable_qtgui_chooser_0_0_group_box.setLayout(self._variable_qtgui_chooser_0_0_box) for i, label in enumerate(self._variable_qtgui_chooser_0_0_labels): radio_button = Qt.QRadioButton(label) self._variable_qtgui_chooser_0_0_box.addWidget(radio_button) self._variable_qtgui_chooser_0_0_button_group.addButton(radio_button, i) self._variable_qtgui_chooser_0_0_callback = lambda i: Qt.QMetaObject.invokeMethod(self._variable_qtgui_chooser_0_0_button_group, "updateButtonChecked", Qt.Q_ARG("int", self._variable_qtgui_chooser_0_0_options.index(i))) self._variable_qtgui_chooser_0_0_callback(self.variable_qtgui_chooser_0_0) self._variable_qtgui_chooser_0_0_button_group.buttonClicked[int].connect( lambda i: self.set_variable_qtgui_chooser_0_0(self._variable_qtgui_chooser_0_0_options[i])) self.top_layout.addWidget(self._variable_qtgui_chooser_0_0_group_box) self.uhd_usrp_source_0_0_0 = uhd.usrp_source( ",".join(("addr0=192.168.70.2,addr1=192.168.20.2,addr2=192.168.30.2,addr3=192.168.50.2", "")), uhd.stream_args( cpu_format="fc32", channels=range(4), ), ) self.uhd_usrp_source_0_0_0.set_clock_source("external", 0) self.uhd_usrp_source_0_0_0.set_time_source("external", 0) self.uhd_usrp_source_0_0_0.set_clock_source("external", 1) self.uhd_usrp_source_0_0_0.set_time_source("external", 1) self.uhd_usrp_source_0_0_0.set_clock_source("external", 2) self.uhd_usrp_source_0_0_0.set_time_source("external", 2) self.uhd_usrp_source_0_0_0.set_clock_source("external", 3) self.uhd_usrp_source_0_0_0.set_time_source("external", 3) self.uhd_usrp_source_0_0_0.set_time_unknown_pps(uhd.time_spec()) self.uhd_usrp_source_0_0_0.set_samp_rate(samp_rate) # Tell boards to run these commands at this specific time in the future cmd_time = self.uhd_usrp_source_0_0_0.get_time_now() + uhd.time_spec_t(1.0) self.uhd_usrp_source_0_0_0.set_command_time(cmd_time,0) self.uhd_usrp_source_0_0_0.set_command_time(cmd_time,1) self.uhd_usrp_source_0_0_0.set_command_time(cmd_time,2) self.uhd_usrp_source_0_0_0.set_command_time(cmd_time,3) self.uhd_usrp_source_0_0_0.set_center_freq(center_freq, 0) self.uhd_usrp_source_0_0_0.set_gain(gain_rx, 0) self.uhd_usrp_source_0_0_0.set_center_freq(center_freq, 1) self.uhd_usrp_source_0_0_0.set_gain(gain_rx, 1) self.uhd_usrp_source_0_0_0.set_center_freq(center_freq, 2) self.uhd_usrp_source_0_0_0.set_gain(gain_rx, 2) self.uhd_usrp_source_0_0_0.set_center_freq(center_freq, 3) self.uhd_usrp_source_0_0_0.set_gain(gain_rx, 3) self.uhd_usrp_source_0_0_0.clear_command_time() time.sleep(1.5) self.uhd_usrp_sink_0_0 = uhd.usrp_sink( ",".join(("addr=192.168.40.2", "")), uhd.stream_args( cpu_format="fc32", channels=range(1), ), ) self.uhd_usrp_sink_0_0.set_clock_source("mimo", 0) self.uhd_usrp_sink_0_0.set_time_source("mimo", 0) self.uhd_usrp_sink_0_0.set_samp_rate(samp_rate) self.uhd_usrp_sink_0_0.set_center_freq(center_freq, 0) self.uhd_usrp_sink_0_0.set_gain(10, 0) self.qtgui_time_sink_x_0_0 = qtgui.time_sink_f( 100, #size samp_rate, #samp_rate "", #name 3 #number of inputs ) self.qtgui_time_sink_x_0_0.set_update_time(0.10) self.qtgui_time_sink_x_0_0.set_y_axis(-1, 1) self.qtgui_time_sink_x_0_0.set_y_label("Amplitude", "") self.qtgui_time_sink_x_0_0.enable_tags(-1, True) self.qtgui_time_sink_x_0_0.set_trigger_mode(qtgui.TRIG_MODE_AUTO, qtgui.TRIG_SLOPE_POS, 0.0, 0, 0, "") self.qtgui_time_sink_x_0_0.enable_autoscale(True) self.qtgui_time_sink_x_0_0.enable_grid(False) self.qtgui_time_sink_x_0_0.enable_control_panel(True) if not True: self.qtgui_time_sink_x_0_0.disable_legend() labels = ["", "", "", "", "", "", "", "", "", ""] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = ["blue", "red", "green", "black", "cyan", "magenta", "yellow", "dark red", "dark green", "blue"] styles = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] markers = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] for i in xrange(3): if len(labels[i]) == 0: self.qtgui_time_sink_x_0_0.set_line_label(i, "Data {0}".format(i)) else: self.qtgui_time_sink_x_0_0.set_line_label(i, labels[i]) self.qtgui_time_sink_x_0_0.set_line_width(i, widths[i]) self.qtgui_time_sink_x_0_0.set_line_color(i, colors[i]) self.qtgui_time_sink_x_0_0.set_line_style(i, styles[i]) self.qtgui_time_sink_x_0_0.set_line_marker(i, markers[i]) self.qtgui_time_sink_x_0_0.set_line_alpha(i, alphas[i]) self._qtgui_time_sink_x_0_0_win = sip.wrapinstance(self.qtgui_time_sink_x_0_0.pyqwidget(), Qt.QWidget) self.top_layout.addWidget(self._qtgui_time_sink_x_0_0_win) self.qtgui_time_sink_x_0 = qtgui.time_sink_f( 1526*2, #size samp_rate, #samp_rate "", #name 4 #number of inputs ) self.qtgui_time_sink_x_0.set_update_time(0.10) self.qtgui_time_sink_x_0.set_y_axis(-1, 1) self.qtgui_time_sink_x_0.set_y_label("Amplitude", "") self.qtgui_time_sink_x_0.enable_tags(-1, True) self.qtgui_time_sink_x_0.set_trigger_mode(qtgui.TRIG_MODE_AUTO, qtgui.TRIG_SLOPE_POS, 0.0, 0, 0, "") self.qtgui_time_sink_x_0.enable_autoscale(True) self.qtgui_time_sink_x_0.enable_grid(False) self.qtgui_time_sink_x_0.enable_control_panel(True) if not True: self.qtgui_time_sink_x_0.disable_legend() labels = ["", "", "", "", "", "", "", "", "", ""] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = ["blue", "red", "green", "black", "cyan", "magenta", "yellow", "dark red", "dark green", "blue"] styles = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] markers = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] for i in xrange(4): if len(labels[i]) == 0: self.qtgui_time_sink_x_0.set_line_label(i, "Data {0}".format(i)) else: self.qtgui_time_sink_x_0.set_line_label(i, labels[i]) self.qtgui_time_sink_x_0.set_line_width(i, widths[i]) self.qtgui_time_sink_x_0.set_line_color(i, colors[i]) self.qtgui_time_sink_x_0.set_line_style(i, styles[i]) self.qtgui_time_sink_x_0.set_line_marker(i, markers[i]) self.qtgui_time_sink_x_0.set_line_alpha(i, alphas[i]) self._qtgui_time_sink_x_0_win = sip.wrapinstance(self.qtgui_time_sink_x_0.pyqwidget(), Qt.QWidget) self.top_layout.addWidget(self._qtgui_time_sink_x_0_win) self.measure_offset_0 = measure_offset( cal_freq=cal_freq, mu=0.0001, samp_rate=samp_rate, ) self.blocks_skiphead_0_1 = blocks.skiphead(gr.sizeof_int*1, 1024*4) self.blocks_skiphead_0_0 = blocks.skiphead(gr.sizeof_int*1, 1024*4) self.blocks_skiphead_0 = blocks.skiphead(gr.sizeof_int*1, 1024*4) self.blocks_message_strobe_0 = blocks.message_strobe(pmt.from_double(variable_qtgui_chooser_0_1_0), 1000) self.blocks_int_to_float_0_1 = blocks.int_to_float(1, 1) self.blocks_int_to_float_0_0 = blocks.int_to_float(1, 1) self.blocks_int_to_float_0 = blocks.int_to_float(1, 1) self.blocks_head_0 = blocks.head(gr.sizeof_int*1, 100) self.blocks_file_sink_0_1 = blocks.file_sink(gr.sizeof_int*1, "/home/travis/Dropbox/PHD/WiFiUS/doa/gnuradio/gr-wifius/data/offsets_chan3_ints.bin", False) self.blocks_file_sink_0_1.set_unbuffered(False) self.blocks_file_sink_0_0 = blocks.file_sink(gr.sizeof_int*1, "/home/travis/Dropbox/PHD/WiFiUS/doa/gnuradio/gr-wifius/data/offsets_chan2_ints.bin", False) self.blocks_file_sink_0_0.set_unbuffered(False) self.blocks_file_sink_0 = blocks.file_sink(gr.sizeof_int*1, "/home/travis/Dropbox/PHD/WiFiUS/doa/gnuradio/gr-wifius/data/offsets_chan1_ints.bin", False) self.blocks_file_sink_0.set_unbuffered(False) self.blocks_complex_to_real_1_0 = blocks.complex_to_real(1) self.blocks_complex_to_real_1 = blocks.complex_to_real(1) self.blocks_complex_to_real_0_0 = blocks.complex_to_real(1) self.blocks_complex_to_real_0 = blocks.complex_to_real(1) self.analog_sig_source_x_0 = analog.sig_source_c(samp_rate, analog.GR_COS_WAVE, cal_freq, 1, 0) ################################################## # Connections ################################################## self.msg_connect((self.blocks_message_strobe_0, 'strobe'), (self.measure_offset_0, 'in')) self.connect((self.analog_sig_source_x_0, 0), (self.uhd_usrp_sink_0_0, 0)) self.connect((self.blocks_complex_to_real_0, 0), (self.qtgui_time_sink_x_0, 0)) self.connect((self.blocks_complex_to_real_0_0, 0), (self.qtgui_time_sink_x_0, 2)) self.connect((self.blocks_complex_to_real_1, 0), (self.qtgui_time_sink_x_0, 1)) self.connect((self.blocks_complex_to_real_1_0, 0), (self.qtgui_time_sink_x_0, 3)) self.connect((self.blocks_head_0, 0), (self.blocks_file_sink_0, 0)) self.connect((self.blocks_int_to_float_0, 0), (self.qtgui_time_sink_x_0_0, 0)) self.connect((self.blocks_int_to_float_0_0, 0), (self.qtgui_time_sink_x_0_0, 2)) self.connect((self.blocks_int_to_float_0_1, 0), (self.qtgui_time_sink_x_0_0, 1)) self.connect((self.blocks_skiphead_0, 0), (self.blocks_head_0, 0)) self.connect((self.blocks_skiphead_0_0, 0), (self.blocks_file_sink_0_0, 0)) self.connect((self.blocks_skiphead_0_1, 0), (self.blocks_file_sink_0_1, 0)) self.connect((self.measure_offset_0, 0), (self.blocks_int_to_float_0, 0)) self.connect((self.measure_offset_0, 2), (self.blocks_int_to_float_0_0, 0)) self.connect((self.measure_offset_0, 1), (self.blocks_int_to_float_0_1, 0)) self.connect((self.measure_offset_0, 0), (self.blocks_skiphead_0, 0)) self.connect((self.measure_offset_0, 1), (self.blocks_skiphead_0_0, 0)) self.connect((self.measure_offset_0, 2), (self.blocks_skiphead_0_1, 0)) self.connect((self.uhd_usrp_source_0_0_0, 0), (self.blocks_complex_to_real_0, 0)) self.connect((self.uhd_usrp_source_0_0_0, 2), (self.blocks_complex_to_real_0_0, 0)) self.connect((self.uhd_usrp_source_0_0_0, 1), (self.blocks_complex_to_real_1, 0)) self.connect((self.uhd_usrp_source_0_0_0, 3), (self.blocks_complex_to_real_1_0, 0)) self.connect((self.uhd_usrp_source_0_0_0, 0), (self.measure_offset_0, 0)) self.connect((self.uhd_usrp_source_0_0_0, 1), (self.measure_offset_0, 1)) self.connect((self.uhd_usrp_source_0_0_0, 2), (self.measure_offset_0, 2)) self.connect((self.uhd_usrp_source_0_0_0, 3), (self.measure_offset_0, 3))
def __init__(self, center_frequency, sample_rate, decimation, filename, sample_format=None, threshold=7.0, burst_width=40e3, offline=False, max_queue_len=500, handle_multiple_frames_per_burst=False, raw_capture_filename=None, debug_id=None, max_bursts=0, verbose=False, file_info="", samples_per_symbol=10, config={}): gr.top_block.__init__(self, "Top Block") self.handle_sigint = False self._center_frequency = center_frequency self._burst_width = burst_width self._input_sample_rate = sample_rate self._verbose = verbose self._threshold = threshold self._filename = filename self._offline = offline self._max_queue_len = max_queue_len self._handle_multiple_frames_per_burst = handle_multiple_frames_per_burst self._decimation = decimation # Sample rate of the bursts exiting the burst downmix block self._burst_sample_rate = 25000 * samples_per_symbol if (self._input_sample_rate / self._decimation) % self._burst_sample_rate != 0: raise RuntimeError("Selected sample rate and decimation can not be matched. Please try a different combination. Sample rate divided by decimation must be a multiple of %d." % self._burst_sample_rate) self._fft_size = 2**round(math.log(self._input_sample_rate / 1000, 2)) # FFT is approx. 1 ms long self._burst_pre_len = 2 * self._fft_size # Keep 16 ms of signal after the FFT loses track self._burst_post_len = int(self._input_sample_rate * 16e-3) # Just to keep the code below a bit more portable tb = self if self._decimation > 1: self._use_channelizer = True # We will set up a filter bank with an odd number of outputs and # and an over sampling ratio to still get the desired decimation. # The goal is to reconstruct signals which (due to Doppler shift) end up # on the border of two channels. # For this to work the desired decimation must be even. if self._decimation % 2: raise RuntimeError("The desired decimation must be 1 or an even number.") self._channels = self._decimation + 1 if self._decimation >= 8: self._use_fft_channelizer = True if 2**int(math.log(self._decimation, 2)) != self._decimation: raise RuntimeError("Decimations >= 8 must be a power of two.") self._channel_sample_rate = self._input_sample_rate // self._decimation # On low end ARM machines we only create a single burst downmixer to not # overload the CPU. Rather drop bursts than samples. if platform.machine() == 'aarch64' and multiprocessing.cpu_count() == 4: self._n_burst_downmixers = 1 else: self._n_burst_downmixers = 2 else: self._use_fft_channelizer = False self._n_burst_downmixers = self._channels self._channelizer_over_sample_ratio = self._channels / (self._channels - 1.) channelizer_output_sample_rate = int(round(float(self._input_sample_rate) / self._channels * self._channelizer_over_sample_ratio)) self._channel_sample_rate = channelizer_output_sample_rate assert channelizer_output_sample_rate == self._input_sample_rate / self._decimation assert channelizer_output_sample_rate % self._burst_sample_rate == 0 # The over sampled region of the FIR filter contains half of the signal width and # the transition region of the FIR filter. # The bandwidth is simply increased by the signal width. # A signal which has its center frequency directly on the border of # two channels will reconstruct correctly on both channels. self._fir_bw = (self._input_sample_rate / self._channels + self._burst_width) / 2 # The remaining bandwidth inside the over sampled region is used to # contain the transition region of the filter. # It can be multiplied by two as it is allowed to continue into the # transition region of the neighboring channel. # Some details can be found here: https://youtu.be/6ngYp8W-AX0?t=2289 self._fir_tw = (channelizer_output_sample_rate / 2 - self._fir_bw) * 2 # Real world data shows only a minor degradation in performance when # doubling the transition width. self._fir_tw *= 2 # If the over sampling ratio is not large enough, there is not # enough room to construct a transition region. if self._fir_tw < 0: raise RuntimeError("PFB over sampling ratio not enough to create a working FIR filter. Please try a different decimation.") self._pfb_fir_filter = gnuradio.filter.firdes.low_pass_2(1, self._input_sample_rate, self._fir_bw, self._fir_tw, 60) # If the transition width approaches 0, the filter size goes up significantly. if len(self._pfb_fir_filter) > 300: print("Warning: The PFB FIR filter has an abnormal large number of taps:", len(self._pfb_fir_filter), file=sys.stderr) print("Consider reducing the decimation factor or use a decimation >= 8.", file=sys.stderr) pfb_input_delay = (len(self._pfb_fir_filter) + 1) // 2 - self._channels / self._channelizer_over_sample_ratio self._channelizer_delay = pfb_input_delay / self._decimation if self._verbose: print("self._channels", self._channels, file=sys.stderr) print("len(self._pfb_fir_filter)", len(self._pfb_fir_filter), file=sys.stderr) print("self._channelizer_over_sample_ratio", self._channelizer_over_sample_ratio, file=sys.stderr) print("self._fir_bw", self._fir_bw, file=sys.stderr) print("self._fir_tw", self._fir_tw, file=sys.stderr) print("self._channel_sample_rate", self._channel_sample_rate, file=sys.stderr) else: self._use_channelizer = False self._channel_sample_rate = self._input_sample_rate self._channels = 1 # After 90 ms there needs to be a pause in the frame sturcture. # Let's make that the limit for a detected burst self._max_burst_len = int(self._channel_sample_rate * 0.09) if self._verbose: print("require %.1f dB" % self._threshold, file=sys.stderr) print("burst_width: %d Hz" % self._burst_width, file=sys.stderr) print("source:", config['source'], file=sys.stderr) if config['source'] == 'osmosdr': d = config["osmosdr-source"] # work around https://github.com/gnuradio/gnuradio/issues/5121 sys.path.append('/usr/local/lib/python3/dist-packages') import osmosdr if 'device_args' in d: source = osmosdr.source(args=d['device_args']) else: source = osmosdr.source() source.set_sample_rate(self._input_sample_rate) source.set_center_freq(self._center_frequency, 0) # Set a rough time estimate for potential rx_time tags from USRP devices # This prevents the output from having bogous time stamps if no GPSDO is available source.set_time_now(osmosdr.time_spec_t(time.time())) if 'gain' in d: gain = int(d['gain']) source.set_gain(gain, 0) print("(RF) Gain:", source.get_gain(0), '(Requested %d)' % gain, file=sys.stderr) for key, value in d.items(): if key.endswith("_gain"): gain_option_name = key.split('_')[0] gain_value = int(value) def match_gain(gain, gain_names): for gain_name in gain_names: if gain.lower() == gain_name.lower(): return gain_name return None gain_name = match_gain(gain_option_name, source.get_gain_names()) if gain_name is not None: source.set_gain(gain_value, gain_name, 0) print(gain_name, "Gain:", source.get_gain(gain_name, 0), '(Requested %d)' % gain_value, file=sys.stderr) else: print("WARNING: Gain", gain_option_name, "not supported by source!", file=sys.stderr) print("Supported gains:", source.get_gain_names(), file=sys.stderr) if 'bandwidth' in d: bandwidth = int(d['bandwidth']) source.set_bandwidth(bandwidth, 0) print("Bandwidth:", source.get_bandwidth(0), '(Requested %d)' % bandwidth, file=sys.stderr) else: source.set_bandwidth(0, 0) print("Warning: Setting bandwidth to", source.get_bandwidth(0), file=sys.stderr) if 'antenna' in d: antenna = d['antenna'] source.set_antenna(antenna, 0) print("Antenna:", source.get_antenna(0), '(Requested %s)' % antenna, file=sys.stderr) else: print("Warning: Setting antenna to", source.get_antenna(0), file=sys.stderr) if 'clock_source' in d: print("Setting clock source to:", d['clock_source'], file=sys.stderr) source.set_clock_source(d['clock_source'], 0) if 'time_source' in d: print("Setting time source to:", d['time_source'], file=sys.stderr) source.set_time_source(d['time_source'], 0) while (time.time() % 1) < 0.4 or (time.time() % 1) > 0.6: pass t = time.time() source.set_time_next_pps(osmosdr.time_spec_t(int(t) + 1)) time.sleep(1) #source.set_freq_corr($corr0, 0) #source.set_dc_offset_mode($dc_offset_mode0, 0) #source.set_iq_balance_mode($iq_balance_mode0, 0) #source.set_gain_mode($gain_mode0, 0) elif config['source'] == 'soapy': d = config["soapy-source"] try: from gnuradio import soapy except ImportError: raise ImportError("gr-soapy not found. Make sure you are running GNURadio >= 3.9.2.0") if 'driver' not in d: print("No driver specified for soapy", file=sys.stderr) print("Run 'SoapySDRUtil -i' to see available drivers(factories)", file=sys.stderr) exit(1) dev = 'driver=' + d['driver'] # Strip quotes def sanitize(s): if s.startswith('"') and s.endswith('"'): return s.strip('""') if s.startswith("'") and s.endswith("'"): return s.strip("''") return s # Remove all outer quotes from the args if they are present in the config if 'device_args' in d: dev_args = sanitize(d['device_args']) elif 'dev_args' in d: dev_args = sanitize(d['dev_args']) else: dev_args = '' stream_args = sanitize(d['stream_args']) if 'stream_args' in d else '' tune_args = sanitize(d['tune_args']) if 'tune_args' in d else '' other_settings = sanitize(d['other_settings']) if 'other_settings' in d else '' # We only support a single channel. Apply tune_args and other_settings to that channel. source = soapy.source(dev, "fc32", 1, dev_args, stream_args, [tune_args], [other_settings]) source.set_sample_rate(0, self._input_sample_rate) source.set_frequency(0, self._center_frequency) if 'gain' in d: gain = int(d['gain']) source.set_gain_mode(0, False) # AGC: OFF source.set_gain(0, gain) print("Gain:", source.get_gain(0), '(Requested %d)' % gain, file=sys.stderr) for key, value in d.items(): if key.endswith("_gain"): gain_option_name = key.split('_')[0] gain_value = int(value) def match_gain(gain, gain_names): for gain_name in gain_names: if gain.lower() == gain_name.lower(): return gain_name return None gain_name = match_gain(gain_option_name, source.list_gains(0)) if gain_name is not None: source.set_gain(0, gain_name, gain_value) print(gain_name, "Gain:", source.get_gain(0, gain_name), '(Requested %d)' % gain_value, source.get_gain_range(0, gain_name), file=sys.stderr) else: print("WARNING: Gain", gain_option_name, "not supported by source!", file=sys.stderr) print("Supported gains:", source.list_gains(0), file=sys.stderr) if 'bandwidth' in d: bandwidth = int(d['bandwidth']) source.set_bandwidth(0, bandwidth) print("Bandwidth:", source.get_bandwidth(0), '(Requested %d)' % bandwidth, file=sys.stderr) else: source.set_bandwidth(0, 0) print("Warning: Setting bandwidth to", source.get_bandwidth(0), file=sys.stderr) if 'antenna' in d: antenna = d['antenna'] source.set_antenna(0, antenna) print("Antenna:", source.get_antenna(0), '(Requested %s)' % antenna, file=sys.stderr) else: print("Warning: Setting antenna to", source.get_antenna(0), file=sys.stderr) #source.set_frequency_correction(0, f_corr) #source.set_dc_offset_mode(0, True) #source.set_dc_offset(0, dc_off) #source.set_iq_balance(0, iq_bal) elif config['source'] == 'zeromq-sub': d = config["zeromq-sub-source"] from gnuradio import zeromq if 'address' not in d: print("No address specified for zeromq sub", file=sys.stderr) exit(1) pass_tags = False if 'pass_tags' in d: pass_tags = bool(distutils.util.strtobool(d['pass_tags'])) timeout = 100 if 'timeout' in d: timeout = int(d['timeout']) high_water_mark = -1 if 'high_water_mark' in d: high_water_mark = int(d['high_water_mark']) source = zeromq.sub_source(gr.sizeof_gr_complex, 1, d['address'], timeout, pass_tags, high_water_mark, '') elif config['source'] == 'uhd': d = config["uhd-source"] from gnuradio import uhd dev_addr = "" if "device_addr" in d: dev_addr = d['device_addr'] dev_args = d['device_args'] cpu_format = 'fc32' wire_format = 'sc16' stream_args = "" stream_args = uhd.stream_args(cpu_format, wire_format, args=stream_args) source = uhd.usrp_source(dev_addr + "," + dev_args, stream_args) source.set_samp_rate(self._input_sample_rate) source.set_center_freq(self._center_frequency) if 'gain' in d: gain = int(d['gain']) source.set_gain(gain, 0) print("Gain:", source.get_gain(0), '(Requested %d)' % gain, file=sys.stderr) if 'bandwidth' in d: bandwidth = int(d['bandwidth']) source.set_bandwidth(bandwidth, 0) print("Bandwidth:", source.get_bandwidth(0), '(Requested %d)' % bandwidth, file=sys.stderr) else: source.set_bandwidth(0) print("Warning: Setting bandwidth to", source.get_bandwidth(0), file=sys.stderr) if 'antenna' in d: antenna = d['antenna'] source.set_antenna(antenna, 0) print("Antenna:", source.get_antenna(0), '(Requested %s)' % antenna, file=sys.stderr) else: print("Warning: Setting antenna to", source.get_antenna(0), file=sys.stderr) print("mboard sensors:", source.get_mboard_sensor_names(0), file=sys.stderr) #for sensor in source.get_mboard_sensor_names(0): # print(sensor, source.get_mboard_sensor(sensor, 0)) gpsdo_sources = ('gpsdo', 'jacksonlabs') time_source = None if 'time_source' in d: time_source = d['time_source'] if time_source in gpsdo_sources: source.set_time_source("gpsdo", 0) else: source.set_time_source(time_source, 0) clock_source = None if 'clock_source' in d: clock_source = d['time_source'] if clock_source in gpsdo_sources: source.set_clock_source("gpsdo", 0) else: source.set_clock_source(clock_source, 0) if time_source in gpsdo_sources or clock_source in gpsdo_sources: print("Waiting for gps_locked...", file=sys.stderr) while True: try: if d['time_source'] == "jacksonlabs": servo = source.get_mboard_sensor("gps_servo", 0) # See https://lists.ettus.com/empathy/thread/6ZOCFQSKLHSG2IH3ID7XPWVKHVHZXPBP gps_locked = str(servo).split()[8] == "6" else: gps_locked = source.get_mboard_sensor("gps_locked", 0).to_bool() if gps_locked: break except ValueError as e: print(e, file=sys.stderr) pass time.sleep(1) print("gps_locked!", file=sys.stderr) if clock_source: print("Waiting for ref_locked...", file=sys.stderr) while True: try: ref_locked = source.get_mboard_sensor("ref_locked", 0) if ref_locked.to_bool(): break except ValueError as e: print(e, file=sys.stderr) pass time.sleep(1) print("ref_locked!", file=sys.stderr) if time_source: if time_source in gpsdo_sources: while True: try: gps_time = uhd.time_spec_t(source.get_mboard_sensor("gps_time").to_int()) break except ValueError as e: print(e, file=sys.stderr) pass time.sleep(1) next_pps_time = gps_time + 1 else: system_time = uhd.time_spec_t(int(time.time())) next_pps_time = system_time + 1 source.set_time_next_pps(next_pps_time) print("Next PPS at", next_pps_time.get_real_secs(), file=sys.stderr) print("Sleeping 2 seconds...", file=sys.stderr) time.sleep(2) # TODO: Check result for plausibility print("USRP time:", source.get_time_last_pps(0).get_real_secs(), file=sys.stderr) else: # Set a rough time estimate for rx_time tags from the USRP. # This prevents the output from having bogous time stamps if no GPSDO is available. source.set_time_now(uhd.time_spec_t(time.time())) self.source = source else: if sample_format == "cu8": converter = iridium.iuchar_to_complex() itemsize = gr.sizeof_char scale = 1 itemtype = np.uint8 elif sample_format == "ci8": converter = blocks.interleaved_char_to_complex() itemsize = gr.sizeof_char scale = 1 / 128. itemtype = np.int8 elif sample_format == "ci16_le": converter = blocks.interleaved_short_to_complex() itemsize = gr.sizeof_short scale = 1 / 32768. itemtype = np.int16 elif sample_format == "cf32_le": converter = None itemsize = gr.sizeof_gr_complex itemtype = np.complex64 else: raise RuntimeError("Unknown sample format for offline mode given") if config['source'] == 'stdin': file_source = blocks.file_descriptor_source(itemsize=itemsize, fd=0, repeat=False) elif config['source'] == 'object': from iridium.file_object_source import file_object_source file_source = file_object_source(fileobject=config['object'], itemtype=itemtype) else: file_source = blocks.file_source(itemsize=itemsize, filename=config['file'], repeat=False) self.source = file_source # XXX: keep reference if converter: multi = blocks.multiply_const_cc(scale) tb.connect(file_source, converter, multi) source = multi else: source = file_source self._fft_burst_tagger = iridium.fft_burst_tagger(center_frequency=self._center_frequency, fft_size=self._fft_size, sample_rate=self._input_sample_rate, burst_pre_len=self._burst_pre_len, burst_post_len=self._burst_post_len, burst_width=int(self._burst_width), max_bursts=max_bursts, max_burst_len=int(self._input_sample_rate * 0.09), threshold=self._threshold, history_size=512, offline=self._offline, debug=self._verbose) self._fft_burst_tagger.set_min_output_buffer(1024 * 64) # Initial filter to filter the detected bursts. Runs at burst_sample_rate. Used to decimate the signal. input_filter = gnuradio.filter.firdes.low_pass_2(1, self._channel_sample_rate, self._burst_width / 2, self._burst_width, 40) #input_filter = gnuradio.filter.firdes.low_pass_2(1, self._channel_sample_rate, 42e3/2, 24e3, 40) #print len(input_filter) # Filter to find the start of the signal. Should be fairly narrow. start_finder_filter = gnuradio.filter.firdes.low_pass_2(1, self._burst_sample_rate, 5e3 / 2, 10e3 / 2, 60) #print len(start_finder_filter) self._iridium_qpsk_demod = iridium.iridium_qpsk_demod(self._channels) self._frame_sorter = iridium.frame_sorter() self._iridium_frame_printer = iridium.iridium_frame_printer(file_info) if raw_capture_filename: multi = blocks.multiply_const_cc(32768) converter = blocks.complex_to_interleaved_short() raw_sink = blocks.file_sink(itemsize=gr.sizeof_short, filename=raw_capture_filename + '.sigmf-data') tb.connect(source, multi, converter, raw_sink) # Enable the following if not fast enough #self._burst_to_pdu_converters = [] #self._burst_downmixers = [] #return tb.connect(source, self._fft_burst_tagger) if self._use_channelizer: self._burst_to_pdu_converters = [] self._burst_downmixers = [] sinks = [] for channel in range(self._channels): if not self._use_fft_channelizer: center = channel if channel <= self._channels / 2 else (channel - self._channels) relative_center = center / float(self._channels) relative_span = 1. / self._channels relative_sample_rate = relative_span * self._channelizer_over_sample_ratio # Second and third parameters tell the block where after the PFB it sits. burst_to_pdu_converter = iridium.tagged_burst_to_pdu(self._max_burst_len, relative_center, relative_span, relative_sample_rate, -self._channelizer_delay, self._max_queue_len, not self._offline) self._burst_to_pdu_converters.append(burst_to_pdu_converter) burst_downmixer = iridium.burst_downmix(self._burst_sample_rate, int(0.007 * self._burst_sample_rate), 0, (input_filter), (start_finder_filter), self._handle_multiple_frames_per_burst) if debug_id is not None: burst_downmixer.debug_id(debug_id) self._burst_downmixers.append(burst_downmixer) channelizer_debug_sinks = [] #channelizer_debug_sinks = [blocks.file_sink(itemsize=gr.sizeof_gr_complex, filename="/tmp/channel-%d.f32"%i) for i in range(self._channels)] if self._use_fft_channelizer: if not channelizer_debug_sinks and self._offline: # HACK: if there are no stream outputs active GNURadio has issues terminating the # flowgraph on completion. Connect some dummy sinks to them. channelizer_debug_sinks = [blocks.null_sink(gr.sizeof_gr_complex) for i in range(self._channels)] activate_streams = len(channelizer_debug_sinks) > 0 self._channelizer = iridium.fft_channelizer(1024, self._channels - 1, activate_streams, self._n_burst_downmixers, self._max_burst_len, self._max_queue_len * self._n_burst_downmixers, not self._offline) else: self._channelizer = gnuradio.filter.pfb.channelizer_ccf(numchans=self._channels, taps=self._pfb_fir_filter, oversample_rate=self._channelizer_over_sample_ratio) tb.connect(self._fft_burst_tagger, self._channelizer) for i in range(self._channels): if channelizer_debug_sinks: tb.connect((self._channelizer, i), channelizer_debug_sinks[i]) for i in range(self._n_burst_downmixers): if self._burst_to_pdu_converters: tb.connect((self._channelizer, i), self._burst_to_pdu_converters[i]) tb.msg_connect((self._burst_to_pdu_converters[i], 'cpdus'), (self._burst_downmixers[i], 'cpdus')) tb.msg_connect((self._burst_downmixers[i], 'burst_handled'), (self._burst_to_pdu_converters[i], 'burst_handled')) else: tb.msg_connect((self._channelizer, 'cpdus%d' % i), (self._burst_downmixers[i], 'cpdus')) tb.msg_connect((self._burst_downmixers[i], 'burst_handled'), (self._channelizer, 'burst_handled')) tb.msg_connect((self._burst_downmixers[i], 'cpdus'), (self._iridium_qpsk_demod, 'cpdus%d' % i)) else: burst_downmix = iridium.burst_downmix(self._burst_sample_rate, int(0.007 * self._burst_sample_rate), 0, (input_filter), (start_finder_filter), self._handle_multiple_frames_per_burst) if debug_id is not None: burst_downmix.debug_id(debug_id) burst_to_pdu = iridium.tagged_burst_to_pdu(self._max_burst_len, 0.0, 1.0, 1.0, 0, self._max_queue_len, not self._offline) tb.connect(self._fft_burst_tagger, burst_to_pdu) tb.msg_connect((burst_to_pdu, 'cpdus'), (burst_downmix, 'cpdus')) tb.msg_connect((burst_downmix, 'burst_handled'), (burst_to_pdu, 'burst_handled')) # Final connection to the demodulator. It prints the output to stdout tb.msg_connect((burst_downmix, 'cpdus'), (self._iridium_qpsk_demod, 'cpdus')) self._burst_downmixers = [burst_downmix] self._burst_to_pdu_converters = [burst_to_pdu] tb.msg_connect((self._iridium_qpsk_demod, 'pdus'), (self._frame_sorter, 'pdus')) tb.msg_connect((self._frame_sorter, 'pdus'), (self._iridium_frame_printer, 'pdus'))
def getUhdUSRPSink(fc, lo_off, inter, gain, addr, sync): """ Tx def getUhdUSRPSink(fc, inter, gain, addr, sync) in: - fc = center frequency - lo_off = LO off - inter = interpolation factor - gain = gain in the tx, only with 2450 - addr = ip address, format = "addr=ip, mimo_mode=" - sync = if True them sync with external clock out: (usrp2, baseband_freq, dxc_freq) - usrp2 sink object - baseband_freq - dxc_freq """ rf_sink = uhd.usrp_sink(addr, uhd.io_type_t.COMPLEX_FLOAT32, 1) # gain gRange = rf_sink.get_gain_range() if gRange.start() <> gRange.stop(): rf_sink.set_gain(gain) print("i: set_gain = " + str(rf_sink.set_gain())) else: print("i: this daughterboard not support the set gain behavior") # samo freq rf_sink.set_samp_rate(rf_sink.get_clock_rate()/inter) print("i: samp_freq = " + str(rf_sink.get_samp_rate())) # center freq freqRange = rf_sink.get_freq_range() if float(freqRange.start()) > fc and float(freqRange.stop()) < fc: fc = float(freqRange.start()+freqRange.stop())/2 print("e: fc have to be between [" + str(freqRange.start()) + ", " + str(freqRange.stop()) + "]") tune_request = uhd.tune_request_t(fc, lo_off) tune_res = rf_sink.set_center_freq(tune_request) # tune_res = rf_sink.set_center_freq(fc) rf_freq = tune_res.actual_rf_freq dxc_freq = 0 print("i: actual_rf_freq = " + str(rf_freq) + "\ni: actual_dsp_freq = " + str(tune_res.actual_dsp_freq) + "\ni: target_rf_freq = " + str(tune_res.target_rf_freq) + "\ni: target_dsp_freq = " + str(tune_res.target_dsp_freq)) # sync if type(sync) == type(False) and bool(sync): # print "i: sync to pps = " + str(rf_sink.set_time_unknown_pps(uhd.time_spec_t())) # print "i: sync to pps = " + str(rf_sink.set_time_next_pps(uhd.time_spec_t())) # Common references signals ccfg = uhd.clock_config_t() ccfg.ref_source = uhd.clock_config_t.REF_SMA ccfg.pps_source = uhd.clock_config_t.PPS_SMA ccfg.pps_polarity = uhd.clock_config_t.PPS_NEG rf_sink.set_clock_config(ccfg) #EO CRS # sync the device time # last_pps_time = rf_sink.get_time_last_pps() # while (last_pps_time != rf_sink.get_time_last_pps()): # time.sleep(0.1) rf_sink.set_time_next_pps(uhd.time_spec_t(0.0)) print("i: sync == True") else: print("i: sync == False") # time.sleep(2) return (rf_sink, rf_freq, dxc_freq)
def getUhdUSRP2Source(fc, lo_off, dec, gain, addr, sync): """ Rx def getUhdUSRP2Source(fc, dec, gain, addr, sync): in: - fc = center frequency - dec = decimation factor - gain = gain in the tx, only with 2450 - addr = ip address, format = "addr=ip, mimo_mode=" - sync = if True them sync with external clock out: (usrp2, baseband_freq, dxc_freq) - usrp2 source object - baseband_freq - dxc_freq """ rf_src = uhd.usrp_source(addr, uhd.io_type_t.COMPLEX_FLOAT32, 1) # gain gRange = rf_src.get_gain_range() if gRange.start() <> gRange.stop(): rf_src.set_gain(gain) print("i: set_gain = " + str(rf_src.get_gain())) else: print("i: this daughterboard not support the set gain behavior") # samo freq rf_src.set_samp_rate(rf_src.get_clock_rate()/dec) print("i: samp_freq = " + str(rf_src.get_samp_rate())) # center freq freqRange = rf_src.get_freq_range() if float(freqRange.start()) > fc and float(freqRange.stop()) < fc: fc = float(freqRange.start()+freqRange.stop())/2 print("e: fc have to be between [" + str(freqRange.start()) + ", " + str(freqRange.stop()) + "]") tune_request = uhd.tune_request_t(fc, lo_off) tune_res = rf_src.set_center_freq(tune_request) rf_freq = tune_res.actual_rf_freq dxc_freq = 0 print("i: actual_rf_freq = " + str(rf_freq) + "\ni: actual_dsp_freq = " + str(tune_res.actual_dsp_freq) + "\ni: target_rf_freq = " + str(tune_res.target_rf_freq) + "\ni: target_dsp_freq = " + str(tune_res.target_dsp_freq)) # sync if type(sync) == type(False) and bool(sync): ## print "i: sync to pps = " + str(rf_src.set_time_unknown_pps(uhd.time_spec_t())) ## print "i: sync to pps = " + str(rf_src.set_time_next_pps(uhd.time_spec_t())) # print "i: sync to pps = " + str(rf_src.set) # rf_src.set_time_next_pps(uhd.time_spec_t(uhd.time_spec_t.get_system_time().get_real_secs()+1)) # Common references signals ccfg = uhd.clock_config_t() ccfg.ref_source = uhd.clock_config_t.REF_SMA ccfg.pps_source = uhd.clock_config_t.PPS_SMA ccfg.pps_polarity = uhd.clock_config_t.PPS_NEG rf_src.set_clock_config(ccfg) #EO CRS # sync the device time # last_pps_time = rf_src.get_time_last_pps() # while (last_pps_time != rf_src.get_time_last_pps()): # time.sleep(0.1) # rf_src.set_time_unknown_pps(uhd.time_spec_t(0.0)) rf_src.set_time_next_pps(uhd.time_spec_t(0.0)) print("i: sync == True") # EO SDT else: print("i: sync == False") # time.sleep(1) return (rf_src, rf_freq, dxc_freq) #def getUSRP2Sink(fc, inter, gain, eth, sync): # """ # Tx # def getUSRP2Sink(fc, inter, gain, eth, sync): # # in: # - fc = center frequency # - inter = interpolation factor # - gain = gain in the tx, only with 2450 # - eth = ethernet interface name(String) # - sync = if True them sync with external clock # # out: # (usrp2, baseband_freq, dxc_freq) # - usrp2 sink object # - baseband_freq # - dxc_freq # """ # rf_sink = usrp2.sink_32fc(eth) # # if rf_sink.gain_max() <> rf_sink.gain_min(): # print("i: set_gain = " + str(rf_sink.set_gain(gain))) # else: # print("i: this daughterboard not support the set gain behavior") # # print("i: set inter = " +str(rf_sink.set_interp(inter))) # tune_res = rf_sink.set_center_freq(fc) # # baseband_freq = tune_res.baseband_freq # dxc_freq = tune_res.dxc_freq # print("i: set center freq = " + str(baseband_freq) + # "\ni: residual freq = " + str(tune_res.residual_freq) + # "\ni: dxc freq = " + str(dxc_freq)) # # if type(sync) == type(False) and bool(sync): ## print "i: sync to mimo = " + str(rf_sink.config_mimo(usrp2.MC_WE_LOCK_TO_MIMO)) # print "i: sync to pps = " + str(rf_sink.sync_to_pps()) # print "i: sync to ref clock = " + str(rf_sink.config_mimo(usrp2.MC_WE_LOCK_TO_SMA)) # else: # print "i: ref clock don't lock = " + str(rf_sink.config_mimo(usrp2.MC_WE_DONT_LOCK)) # # print("i: samp_freq = " + str(float(rf_sink.dac_rate())/inter)) # # return (rf_sink, baseband_freq, dxc_freq) #def getUSRP2Source(fc, dec, gain, eth, sync): # """ # Rx # def getUSRP2Source(fc, dec, gain, eth, sync): # # in: # - fc = center frequency # - dec = decimation factor # - gain = gain in the tx, only with 2450 # - eth = ethernet interface name(String) # - sync = if True them sync with external clock # # out: # (usrp2, baseband_freq, dxc_freq) # - usrp2 source object # - baseband_freq # - dxc_freq # """ # # rf_src = usrp2.source_32fc(eth) # # print("i: set_gain = " + str(rf_src.set_gain(gain))) # print("i: set int = " +str(rf_src.set_decim(dec))) # tune_res = rf_src.set_center_freq(fc) # # baseband_freq = tune_res.baseband_freq # dxc_freq = tune_res.dxc_freq # print("i: set center freq = " + str(baseband_freq) + # "\ni: residual freq = " + str(tune_res.residual_freq) + # "\ni: dxc freq = " + str(dxc_freq)) # # if type(sync) == type(False) and bool(sync): ## print "i: sync to mimo = " + str(rf_src.config_mimo(usrp2.MC_PROVIDE_CLK_TO_MIMO)) # print "i: sync to pps = " + str(rf_src.sync_to_pps()) # print "i: sync to ref clock = " + str(rf_src.config_mimo(usrp2.MC_WE_LOCK_TO_SMA)) # else: # print "i: ref clock don't lock = " + str(rf_src.config_mimo(usrp2.MC_WE_DONT_LOCK)) # # print("i: samp_freq = " + str(float(rf_src.adc_rate())/dec)) # # return (rf_src, baseband_freq, dxc_freq)
def coreTest(self, rx_gain, tx_amp, centre_freq, sample_rate=20e6): """ |<------------ TX CHAIN ---------->| |<----- RX CHAIN ---->| +------+ +------+ +--------+ +--------+ | | | | +---------+ | sig[0] |--->| c2s[0] |--->|ch0 | | ch0|--->| vsnk[0] | +--------+ +--------+ | | | | +---------+ +--------+ +--------+ | | | | +---------+ | sig[1] |--->| c2s[1] |--->|ch1 | | ch1|--->| vsnk[1] | +--------+ +--------+ | | | | +---------+ +--------+ +--------+ | | | | +---------+ | sig[2] |--->| c2s[2] |--->|ch2 | | ch2|--->| vsnk[2] | +--------+ +--------+ | | | | +---------+ +--------+ +--------+ | | | | +---------+ | sig[3] |--->| c2s[3] |--->|ch3 | | ch3|--->| vsnk[3] | +--------+ +--------+ | csnk | | csrc | +---------+ +------+ +------+ """ # Is above 40 MHz, disable Channels C & D if centre_freq > 40e6: self.channels = range(2) tb = gr.top_block() # Variables. wave_freq = 1e6 sc = uhd.stream_cmd_t(uhd.stream_cmd_t.STREAM_MODE_NUM_SAMPS_AND_DONE) sc.num_samps = 64 # Blocks and Connections (TX CHAIN). sigs = [ analog.sig_source_c(sample_rate, analog.GR_SIN_WAVE, wave_freq, tx_amp, 0.0) for channel in self.channels ] c2ss = [ blocks.complex_to_interleaved_short(True) for channel in self.channels ] csnk = crimson_sink_s(self.channels, sample_rate, centre_freq, 0.0) for channel in self.channels: tb.connect(sigs[channel], c2ss[channel]) tb.connect(c2ss[channel], (csnk, channel)) # Blocks and Connections (RX CHAIN). csrc = crimson_source_c(self.channels, sample_rate, centre_freq, rx_gain) vsnk = [blocks.vector_sink_c() for channel in self.channels] for channel in self.channels: tb.connect((csrc, channel), vsnk[channel]) # Reset TX and RX times to be roughly in sync. csnk.set_time_now(uhd.time_spec_t(0.0)) csrc.set_time_now(uhd.time_spec_t(0.0)) # Issue stream command to start RX chain somewhere in the middle of the test. sc.stream_now = False sc.time_spec = uhd.time_spec_t(self.test_time / 2.0) csrc.issue_stream_cmd(sc) # Run the test. tb.start() time.sleep(self.test_time) tb.stop() tb.wait() # Return a vsnk sample for further processing and verification. # vsnk are to be processed in individual unit tests, eg. def test_xyz_t(self): # Read sigproc.py for further information on signal processing and vsnks. return vsnk, csnk, csrc