Adapt AMSAT DUV flowgraph to gr-soapy

This commit is contained in:
Manolis Surligas 2019-12-19 20:46:46 +02:00
parent 86c3c3246a
commit 9129ebc14b
2 changed files with 1036 additions and 3793 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,55 +1,51 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
##################################################
#
# SPDX-License-Identifier: GPL-3.0
#
# GNU Radio Python Flow Graph # GNU Radio Python Flow Graph
# Title: AMSAT FOX DUV Decoder # Title: AMSAT FOX DUV Decoder
# Author: Thanos Giolias (agiolias@csd.uoc.gr), Nikos Karamolegos (karamolegkos.n@gmail.com), Manolis Surligas (surligas@gmail.com) # Author: Thanos Giolias (agiolias@csd.uoc.gr), Nikos Karamolegos (karamolegkos.n@gmail.com), Manolis Surligas (surligas@gmail.com)
# Description: A DUV Decoder for the AMSAT FOX satellites # Description: A DUV Decoder for the AMSAT FOX satellites
# GNU Radio version: 3.7.13.5 # GNU Radio version: 3.8.0.0
##################################################
from gnuradio import analog from gnuradio import analog
from gnuradio import blocks
from gnuradio import digital
from gnuradio import eng_notation
from gnuradio import filter
from gnuradio import gr
from gnuradio.eng_option import eng_option
from gnuradio.filter import firdes
from gnuradio.filter import pfb
from optparse import OptionParser
import math import math
import osmosdr from gnuradio import digital
from gnuradio import filter
from gnuradio.filter import firdes
from gnuradio import gr
import sys
import signal
from argparse import ArgumentParser
from gnuradio.eng_arg import eng_float, intx
from gnuradio import eng_notation
import satnogs import satnogs
import time import soapy
class satnogs_amsat_fox_duv_decoder(gr.top_block): class satnogs_amsat_fox_duv_decoder(gr.top_block):
def __init__(self, antenna=satnogs.not_set_antenna, baudrate=9600.0, bb_gain=satnogs.not_set_rx_bb_gain, decoded_data_file_path='/tmp/.satnogs/data/data', dev_args=satnogs.not_set_dev_args, doppler_correction_per_sec=20, enable_iq_dump=0, file_path='test.ogg', if_gain=satnogs.not_set_rx_if_gain, iq_file_path='/tmp/iq.dat', lo_offset=100e3, ppm=0, rf_gain=satnogs.not_set_rx_rf_gain, rigctl_port=4532, rx_freq=100e6, rx_sdr_device='usrpb200', samp_rate_rx=satnogs.not_set_samp_rate_rx, udp_IP='127.0.0.1', udp_port=16887, waterfall_file_path='/tmp/waterfall.dat'): def __init__(self, antenna='', bw=0.0, decoded_data_file_path='/tmp/.satnogs/data/data', dev_args='', doppler_correction_per_sec=20, enable_iq_dump=0, file_path='test.wav', gain=0.0, iq_file_path='/tmp/iq.dat', lo_offset=100e3, rigctl_port=4532, rx_freq=100e6, samp_rate_rx=0.0, soapy_rx_device='driver=invalid', udp_IP='127.0.0.1', udp_port=16887, waterfall_file_path='/tmp/waterfall.dat'):
gr.top_block.__init__(self, "AMSAT FOX DUV Decoder") gr.top_block.__init__(self, "AMSAT FOX DUV Decoder")
################################################## ##################################################
# Parameters # Parameters
################################################## ##################################################
self.antenna = antenna self.antenna = antenna
self.baudrate = baudrate self.bw = bw
self.bb_gain = bb_gain
self.decoded_data_file_path = decoded_data_file_path self.decoded_data_file_path = decoded_data_file_path
self.dev_args = dev_args self.dev_args = dev_args
self.doppler_correction_per_sec = doppler_correction_per_sec self.doppler_correction_per_sec = doppler_correction_per_sec
self.enable_iq_dump = enable_iq_dump self.enable_iq_dump = enable_iq_dump
self.file_path = file_path self.file_path = file_path
self.if_gain = if_gain self.gain = gain
self.iq_file_path = iq_file_path self.iq_file_path = iq_file_path
self.lo_offset = lo_offset self.lo_offset = lo_offset
self.ppm = ppm
self.rf_gain = rf_gain
self.rigctl_port = rigctl_port self.rigctl_port = rigctl_port
self.rx_freq = rx_freq self.rx_freq = rx_freq
self.rx_sdr_device = rx_sdr_device
self.samp_rate_rx = samp_rate_rx self.samp_rate_rx = samp_rate_rx
self.soapy_rx_device = soapy_rx_device
self.udp_IP = udp_IP self.udp_IP = udp_IP
self.udp_port = udp_port self.udp_port = udp_port
self.waterfall_file_path = waterfall_file_path self.waterfall_file_path = waterfall_file_path
@ -65,43 +61,146 @@ class satnogs_amsat_fox_duv_decoder(gr.top_block):
################################################## ##################################################
# Blocks # Blocks
################################################## ##################################################
self.satnogs_waterfall_sink_0 = satnogs.waterfall_sink(audio_samp_rate, 0.0, 10, 1024, waterfall_file_path, 1) self.soapy_source_0 = None
if "custom" == 'custom':
dev = soapy_rx_device
else:
dev = 'driver=' + "custom"
if "custom" == 'sdrplay':
f = 'if_mode=' + "Zero-IF" + ',' + 'agc_setpoint=' + str("-30") + ',' + 'biasT_ctrl=' + "True".lower() + ',' + 'rfnotch_ctrl=' + "False".lower() + ',' + 'dabnotch_ctrl=' + "False".lower() + ',' + str(dev_args)
f = f.replace('\"', '')
f = f.replace("\\'", '')
f = f.strip(',')
self.soapy_source_0 = soapy.source(1, dev, f, samp_rate_rx, "fc32")
else:
self.soapy_source_0 = soapy.source(1, dev, dev_args, samp_rate_rx, "fc32")
if 0 != 0:
self.soapy_source_0.set_master_clock_rate(0)
if len('') > 0:
self.soapy_source_0.set_clock_source('')
# Set up dc offsets
if "custom" != 'uhd':
if (self.soapy_source_0.hasDCOffset(0)):
self.soapy_source_0.set_dc_offset(0,0,False == 'True')
if (self.soapy_source_0.hasDCOffset(1)):
self.soapy_source_0.set_dc_offset(1,0,False == 'True')
# Setup IQ Balance
if "custom" != 'uhd':
if (self.soapy_source_0.hasIQBalance(0)):
self.soapy_source_0.set_iq_balance(0,0)
if (self.soapy_source_0.hasIQBalance(1)):
self.soapy_source_0.set_iq_balance(1,0)
# Setup Frequency correction
if (self.soapy_source_0.hasFrequencyCorrection(0)):
self.soapy_source_0.set_frequency_correction(0,0)
if (self.soapy_source_0.hasFrequencyCorrection(1)):
self.soapy_source_0.set_frequency_correction(1,0)
self.soapy_source_0.set_gain_mode(0,False)
self.soapy_source_0.set_gain_mode(1,False)
self.soapy_source_0.set_frequency(0, rx_freq - lo_offset)
self.soapy_source_0.set_frequency(1, 0)
# Made antenna sanity check more generic
antList = self.soapy_source_0.listAntennas(0)
if len(antList) > 1:
# If we have more than 1 possible antenna
if len(antenna) == 0 or antenna not in antList:
print("ERROR: Please define ant0 to an allowed antenna name.")
strAntList = str(antList).lstrip('(').rstrip(')').rstrip(',')
print("Allowed antennas: " + strAntList)
exit(0)
self.soapy_source_0.set_antenna(0,antenna)
if 1 > 1:
antList = self.soapy_source_0.listAntennas(1)
# If we have more than 1 possible antenna
if len(antList) > 1:
if len('RX2') == 0 or 'RX2' not in antList:
print("ERROR: Please define ant1 to an allowed antenna name.")
strAntList = str(antList).lstrip('(').rstrip(')').rstrip(',')
print("Allowed antennas: " + strAntList)
exit(0)
self.soapy_source_0.set_antenna(1,'RX2')
self.soapy_source_0.set_overall_gain(0,gain, False )
self.soapy_source_0.set_overall_gain(1,10, True )
# Prevent some weird double-gain setting issues for systems with an overall_gain setting
# noticed weird behavior with uhd
if "custom" == 'uhd' or "custom" == 'sidekiq' or "custom" == 'bladerf' or "custom" == 'lime':
self.soapy_source_0.set_gain(0,"PGA", 24, False )
self.soapy_source_0.set_gain(1,"PGA", 24, True )
else:
if "custom" == 'custom':
# If we're here and we're custom, let's still call overall gain
self.soapy_source_0.set_overall_gain(0,gain, False )
self.soapy_source_0.set_overall_gain(1,10, True )
self.soapy_source_0.set_gain(0,"LNA", 10, False )
self.soapy_source_0.set_gain(1,"LNA", 10, True )
self.soapy_source_0.set_gain(0,"TIA", 0, False )
self.soapy_source_0.set_gain(1,"TIA", 0, True )
self.soapy_source_0.set_gain(0,"MIX", 10, False )
self.soapy_source_0.set_gain(1,"MIX", 10, True )
self.soapy_source_0.set_gain(0,"VGA", 10, False )
self.soapy_source_0.set_gain(1,"VGA", 10, True )
# Only rtl-sdr uses TUNER, so just ch0
self.soapy_source_0.set_gain(0,"TUNER", 10, False )
# Only hackrf uses "AMP", so just ch0
self.soapy_source_0.set_gain(0,"AMP", 0, False )
# Only sdrplay uses IFGR so just ch0 for each
self.soapy_source_0.set_gain(0,"IFGR", 59, False )
self.soapy_source_0.set_gain(0,"RFGR", 9, False )
self.satnogs_waterfall_sink_0 = satnogs.waterfall_sink(audio_samp_rate, rx_freq, 10, 1024, waterfall_file_path, 1)
self.satnogs_udp_msg_sink_0_0 = satnogs.udp_msg_sink(udp_IP, udp_port, 1500) self.satnogs_udp_msg_sink_0_0 = satnogs.udp_msg_sink(udp_IP, udp_port, 1500)
self.satnogs_tcp_rigctl_msg_source_0 = satnogs.tcp_rigctl_msg_source("127.0.0.1", rigctl_port, False, int(1000.0/doppler_correction_per_sec) + 1, 1500) self.satnogs_tcp_rigctl_msg_source_0 = satnogs.tcp_rigctl_msg_source("127.0.0.1", rigctl_port, False, int(1000.0/doppler_correction_per_sec) + 1, 1500)
self.satnogs_ogg_encoder_0 = satnogs.ogg_encoder(file_path, audio_samp_rate, 1.0) self.satnogs_ogg_encoder_0 = satnogs.ogg_encoder(file_path, audio_samp_rate, 1.0)
self.satnogs_iq_sink_0 = satnogs.iq_sink(16768, iq_file_path, False, enable_iq_dump) self.satnogs_iq_sink_0 = satnogs.iq_sink(16768, iq_file_path, False, 1)
self.satnogs_frame_file_sink_0_1_0 = satnogs.frame_file_sink(decoded_data_file_path, 0) self.satnogs_frame_file_sink_0_1_0 = satnogs.frame_file_sink(decoded_data_file_path, 0)
self.satnogs_frame_decoder_0 = satnogs.frame_decoder(variable_amsat_duv_decoder_0, gr.sizeof_char) self.satnogs_frame_decoder_0 = satnogs.frame_decoder(variable_amsat_duv_decoder_0, 1 * 1)
self.satnogs_coarse_doppler_correction_cc_0 = satnogs.coarse_doppler_correction_cc(rx_freq, satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx)) self.satnogs_doppler_compensation_0 = satnogs.doppler_compensation(samp_rate_rx, rx_freq, lo_offset, audio_samp_rate, 1)
self.root_raised_cosine_filter_0 = filter.fir_filter_fff(1, firdes.root_raised_cosine( self.root_raised_cosine_filter_0 = filter.fir_filter_fff(
1, 1, 2.4, 0.5, 512)) 1,
self.pfb_arb_resampler_xxx_0 = pfb.arb_resampler_ccf( firdes.root_raised_cosine(
audio_samp_rate/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), 1,
taps=None, 1,
flt_size=32) 2.4,
self.pfb_arb_resampler_xxx_0.declare_sample_delay(0) 0.5,
512))
self.osmosdr_source_0 = osmosdr.source( args="numchan=" + str(1) + " " + satnogs.handle_rx_dev_args(rx_sdr_device, dev_args) ) self.low_pass_filter_1 = filter.fir_filter_fff(
self.osmosdr_source_0.set_sample_rate(satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx)) 100,
self.osmosdr_source_0.set_center_freq(rx_freq - lo_offset, 0) firdes.low_pass(
self.osmosdr_source_0.set_freq_corr(ppm, 0) 1,
self.osmosdr_source_0.set_dc_offset_mode(2, 0) audio_samp_rate,
self.osmosdr_source_0.set_iq_balance_mode(0, 0) 195,
self.osmosdr_source_0.set_gain_mode(False, 0) 10,
self.osmosdr_source_0.set_gain(satnogs.handle_rx_rf_gain(rx_sdr_device, rf_gain), 0) firdes.WIN_HAMMING,
self.osmosdr_source_0.set_if_gain(satnogs.handle_rx_if_gain(rx_sdr_device, if_gain), 0) 6.76))
self.osmosdr_source_0.set_bb_gain(satnogs.handle_rx_bb_gain(rx_sdr_device, bb_gain), 0) self.low_pass_filter_0 = filter.fir_filter_ccf(
self.osmosdr_source_0.set_antenna(satnogs.handle_rx_antenna(rx_sdr_device, antenna), 0) 1,
self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), 0) firdes.low_pass(
1,
self.low_pass_filter_1 = filter.fir_filter_fff(100, firdes.low_pass( audio_samp_rate,
1, audio_samp_rate, 195, 10, firdes.WIN_HAMMING, 6.76)) deviation+max_modulation_freq,
self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass( 3000,
1, audio_samp_rate, deviation+max_modulation_freq, 3000, firdes.WIN_HAMMING, 6.76)) firdes.WIN_HAMMING,
6.76))
self.digital_clock_recovery_mm_xx_0_0_0 = digital.clock_recovery_mm_ff((audio_samp_rate/100.0) / 200, 0.25*0.175*0.175, 0.5, 0.175, 0.005) self.digital_clock_recovery_mm_xx_0_0_0 = digital.clock_recovery_mm_ff((audio_samp_rate/100.0) / 200, 0.25*0.175*0.175, 0.5, 0.175, 0.005)
self.digital_binary_slicer_fb_0_0 = digital.binary_slicer_fb() self.digital_binary_slicer_fb_0_0 = digital.binary_slicer_fb()
self.dc_blocker_xx_0 = filter.dc_blocker_ff(1024, True) self.dc_blocker_xx_0 = filter.dc_blocker_ff(1024, True)
self.blocks_rotator_cc_0 = blocks.rotator_cc(-2.0 * math.pi * (lo_offset / satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx)))
self.analog_quadrature_demod_cf_0_0 = analog.quadrature_demod_cf(1.2) self.analog_quadrature_demod_cf_0_0 = analog.quadrature_demod_cf(1.2)
self.analog_quadrature_demod_cf_0 = analog.quadrature_demod_cf(1.0) self.analog_quadrature_demod_cf_0 = analog.quadrature_demod_cf(1.0)
@ -112,42 +211,34 @@ class satnogs_amsat_fox_duv_decoder(gr.top_block):
################################################## ##################################################
self.msg_connect((self.satnogs_frame_decoder_0, 'out'), (self.satnogs_frame_file_sink_0_1_0, 'frame')) self.msg_connect((self.satnogs_frame_decoder_0, 'out'), (self.satnogs_frame_file_sink_0_1_0, 'frame'))
self.msg_connect((self.satnogs_frame_decoder_0, 'out'), (self.satnogs_udp_msg_sink_0_0, 'in')) self.msg_connect((self.satnogs_frame_decoder_0, 'out'), (self.satnogs_udp_msg_sink_0_0, 'in'))
self.msg_connect((self.satnogs_tcp_rigctl_msg_source_0, 'freq'), (self.satnogs_coarse_doppler_correction_cc_0, 'freq')) self.msg_connect((self.satnogs_tcp_rigctl_msg_source_0, 'freq'), (self.satnogs_doppler_compensation_0, 'doppler'))
self.connect((self.analog_quadrature_demod_cf_0, 0), (self.satnogs_ogg_encoder_0, 0)) self.connect((self.analog_quadrature_demod_cf_0, 0), (self.satnogs_ogg_encoder_0, 0))
self.connect((self.analog_quadrature_demod_cf_0_0, 0), (self.low_pass_filter_1, 0)) self.connect((self.analog_quadrature_demod_cf_0_0, 0), (self.low_pass_filter_1, 0))
self.connect((self.blocks_rotator_cc_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0))
self.connect((self.dc_blocker_xx_0, 0), (self.root_raised_cosine_filter_0, 0)) self.connect((self.dc_blocker_xx_0, 0), (self.root_raised_cosine_filter_0, 0))
self.connect((self.digital_binary_slicer_fb_0_0, 0), (self.satnogs_frame_decoder_0, 0)) self.connect((self.digital_binary_slicer_fb_0_0, 0), (self.satnogs_frame_decoder_0, 0))
self.connect((self.digital_clock_recovery_mm_xx_0_0_0, 0), (self.digital_binary_slicer_fb_0_0, 0)) self.connect((self.digital_clock_recovery_mm_xx_0_0_0, 0), (self.digital_binary_slicer_fb_0_0, 0))
self.connect((self.low_pass_filter_0, 0), (self.analog_quadrature_demod_cf_0, 0)) self.connect((self.low_pass_filter_0, 0), (self.analog_quadrature_demod_cf_0, 0))
self.connect((self.low_pass_filter_0, 0), (self.analog_quadrature_demod_cf_0_0, 0)) self.connect((self.low_pass_filter_0, 0), (self.analog_quadrature_demod_cf_0_0, 0))
self.connect((self.low_pass_filter_1, 0), (self.dc_blocker_xx_0, 0)) self.connect((self.low_pass_filter_1, 0), (self.dc_blocker_xx_0, 0))
self.connect((self.osmosdr_source_0, 0), (self.blocks_rotator_cc_0, 0))
self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.low_pass_filter_0, 0))
self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_iq_sink_0, 0))
self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_waterfall_sink_0, 0))
self.connect((self.root_raised_cosine_filter_0, 0), (self.digital_clock_recovery_mm_xx_0_0_0, 0)) self.connect((self.root_raised_cosine_filter_0, 0), (self.digital_clock_recovery_mm_xx_0_0_0, 0))
self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.pfb_arb_resampler_xxx_0, 0)) self.connect((self.satnogs_doppler_compensation_0, 0), (self.low_pass_filter_0, 0))
self.connect((self.satnogs_doppler_compensation_0, 0), (self.satnogs_iq_sink_0, 0))
self.connect((self.satnogs_doppler_compensation_0, 0), (self.satnogs_waterfall_sink_0, 0))
self.connect((self.soapy_source_0, 0), (self.satnogs_doppler_compensation_0, 0))
def get_antenna(self): def get_antenna(self):
return self.antenna return self.antenna
def set_antenna(self, antenna): def set_antenna(self, antenna):
self.antenna = antenna self.antenna = antenna
self.osmosdr_source_0.set_antenna(satnogs.handle_rx_antenna(self.rx_sdr_device, self.antenna), 0) self.soapy_source_0.set_antenna(0,self.antenna)
def get_baudrate(self): def get_bw(self):
return self.baudrate return self.bw
def set_baudrate(self, baudrate): def set_bw(self, bw):
self.baudrate = baudrate self.bw = bw
self.soapy_source_0.set_bandwidth(0,self.bw)
def get_bb_gain(self):
return self.bb_gain
def set_bb_gain(self, bb_gain):
self.bb_gain = bb_gain
self.osmosdr_source_0.set_bb_gain(satnogs.handle_rx_bb_gain(self.rx_sdr_device, self.bb_gain), 0)
def get_decoded_data_file_path(self): def get_decoded_data_file_path(self):
return self.decoded_data_file_path return self.decoded_data_file_path
@ -179,40 +270,26 @@ class satnogs_amsat_fox_duv_decoder(gr.top_block):
def set_file_path(self, file_path): def set_file_path(self, file_path):
self.file_path = file_path self.file_path = file_path
def get_if_gain(self): def get_gain(self):
return self.if_gain return self.gain
def set_if_gain(self, if_gain): def set_gain(self, gain):
self.if_gain = if_gain self.gain = gain
self.osmosdr_source_0.set_if_gain(satnogs.handle_rx_if_gain(self.rx_sdr_device, self.if_gain), 0) self.soapy_source_0.set_overall_gain(0,self.gain, False )
def get_iq_file_path(self): def get_iq_file_path(self):
return self.iq_file_path return self.iq_file_path
def set_iq_file_path(self, iq_file_path): def set_iq_file_path(self, iq_file_path):
self.iq_file_path = iq_file_path self.iq_file_path = iq_file_path
self.satnogs_iq_sink_0.open(self.iq_file_path)
def get_lo_offset(self): def get_lo_offset(self):
return self.lo_offset return self.lo_offset
def set_lo_offset(self, lo_offset): def set_lo_offset(self, lo_offset):
self.lo_offset = lo_offset self.lo_offset = lo_offset
self.osmosdr_source_0.set_center_freq(self.rx_freq - self.lo_offset, 0) self.soapy_source_0.set_frequency(0, self.rx_freq - self.lo_offset)
self.blocks_rotator_cc_0.set_phase_inc(-2.0 * math.pi * (self.lo_offset / satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)))
def get_ppm(self):
return self.ppm
def set_ppm(self, ppm):
self.ppm = ppm
self.osmosdr_source_0.set_freq_corr(self.ppm, 0)
def get_rf_gain(self):
return self.rf_gain
def set_rf_gain(self, rf_gain):
self.rf_gain = rf_gain
self.osmosdr_source_0.set_gain(satnogs.handle_rx_rf_gain(self.rx_sdr_device, self.rf_gain), 0)
def get_rigctl_port(self): def get_rigctl_port(self):
return self.rigctl_port return self.rigctl_port
@ -225,32 +302,19 @@ class satnogs_amsat_fox_duv_decoder(gr.top_block):
def set_rx_freq(self, rx_freq): def set_rx_freq(self, rx_freq):
self.rx_freq = rx_freq self.rx_freq = rx_freq
self.satnogs_coarse_doppler_correction_cc_0.set_new_freq_locked(self.rx_freq) self.soapy_source_0.set_frequency(0, self.rx_freq - self.lo_offset)
self.osmosdr_source_0.set_center_freq(self.rx_freq - self.lo_offset, 0)
def get_rx_sdr_device(self):
return self.rx_sdr_device
def set_rx_sdr_device(self, rx_sdr_device):
self.rx_sdr_device = rx_sdr_device
self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))
self.osmosdr_source_0.set_sample_rate(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))
self.osmosdr_source_0.set_gain(satnogs.handle_rx_rf_gain(self.rx_sdr_device, self.rf_gain), 0)
self.osmosdr_source_0.set_if_gain(satnogs.handle_rx_if_gain(self.rx_sdr_device, self.if_gain), 0)
self.osmosdr_source_0.set_bb_gain(satnogs.handle_rx_bb_gain(self.rx_sdr_device, self.bb_gain), 0)
self.osmosdr_source_0.set_antenna(satnogs.handle_rx_antenna(self.rx_sdr_device, self.antenna), 0)
self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx), 0)
self.blocks_rotator_cc_0.set_phase_inc(-2.0 * math.pi * (self.lo_offset / satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)))
def get_samp_rate_rx(self): def get_samp_rate_rx(self):
return self.samp_rate_rx return self.samp_rate_rx
def set_samp_rate_rx(self, samp_rate_rx): def set_samp_rate_rx(self, samp_rate_rx):
self.samp_rate_rx = samp_rate_rx self.samp_rate_rx = samp_rate_rx
self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))
self.osmosdr_source_0.set_sample_rate(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) def get_soapy_rx_device(self):
self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx), 0) return self.soapy_rx_device
self.blocks_rotator_cc_0.set_phase_inc(-2.0 * math.pi * (self.lo_offset / satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)))
def set_soapy_rx_device(self, soapy_rx_device):
self.soapy_rx_device = soapy_rx_device
def get_udp_IP(self): def get_udp_IP(self):
return self.udp_IP return self.udp_IP
@ -295,83 +359,81 @@ class satnogs_amsat_fox_duv_decoder(gr.top_block):
def set_audio_samp_rate(self, audio_samp_rate): def set_audio_samp_rate(self, audio_samp_rate):
self.audio_samp_rate = audio_samp_rate self.audio_samp_rate = audio_samp_rate
self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))
self.low_pass_filter_1.set_taps(firdes.low_pass(1, self.audio_samp_rate, 195, 10, firdes.WIN_HAMMING, 6.76))
self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, self.deviation+self.max_modulation_freq, 3000, firdes.WIN_HAMMING, 6.76))
self.digital_clock_recovery_mm_xx_0_0_0.set_omega((self.audio_samp_rate/100.0) / 200) self.digital_clock_recovery_mm_xx_0_0_0.set_omega((self.audio_samp_rate/100.0) / 200)
self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, self.deviation+self.max_modulation_freq, 3000, firdes.WIN_HAMMING, 6.76))
self.low_pass_filter_1.set_taps(firdes.low_pass(1, self.audio_samp_rate, 195, 10, firdes.WIN_HAMMING, 6.76))
def argument_parser(): def argument_parser():
description = 'A DUV Decoder for the AMSAT FOX satellites' description = 'A DUV Decoder for the AMSAT FOX satellites'
parser = OptionParser(usage="%prog: [options]", option_class=eng_option, description=description) parser = ArgumentParser(description=description)
parser.add_option( parser.add_argument(
"", "--antenna", dest="antenna", type="string", default=satnogs.not_set_antenna, "--antenna", dest="antenna", type=str, default='',
help="Set antenna [default=%default]") help="Set antenna [default=%(default)r]")
parser.add_option( parser.add_argument(
"", "--baudrate", dest="baudrate", type="eng_float", default=eng_notation.num_to_str(9600.0), "--bw", dest="bw", type=eng_float, default="0.0",
help="Set baudrate [default=%default]") help="Set Bandwidth [default=%(default)r]")
parser.add_option( parser.add_argument(
"", "--bb-gain", dest="bb_gain", type="eng_float", default=eng_notation.num_to_str(satnogs.not_set_rx_bb_gain), "--decoded-data-file-path", dest="decoded_data_file_path", type=str, default='/tmp/.satnogs/data/data',
help="Set bb_gain [default=%default]") help="Set decoded_data_file_path [default=%(default)r]")
parser.add_option( parser.add_argument(
"", "--decoded-data-file-path", dest="decoded_data_file_path", type="string", default='/tmp/.satnogs/data/data', "--dev-args", dest="dev_args", type=str, default='',
help="Set decoded_data_file_path [default=%default]") help="Set Device arguments [default=%(default)r]")
parser.add_option( parser.add_argument(
"", "--dev-args", dest="dev_args", type="string", default=satnogs.not_set_dev_args, "--doppler-correction-per-sec", dest="doppler_correction_per_sec", type=intx, default=20,
help="Set dev_args [default=%default]") help="Set doppler_correction_per_sec [default=%(default)r]")
parser.add_option( parser.add_argument(
"", "--doppler-correction-per-sec", dest="doppler_correction_per_sec", type="intx", default=20, "--enable-iq-dump", dest="enable_iq_dump", type=intx, default=0,
help="Set doppler_correction_per_sec [default=%default]") help="Set enable_iq_dump [default=%(default)r]")
parser.add_option( parser.add_argument(
"", "--enable-iq-dump", dest="enable_iq_dump", type="intx", default=0, "--file-path", dest="file_path", type=str, default='test.wav',
help="Set enable_iq_dump [default=%default]") help="Set file_path [default=%(default)r]")
parser.add_option( parser.add_argument(
"", "--file-path", dest="file_path", type="string", default='test.ogg', "--gain", dest="gain", type=eng_float, default="0.0",
help="Set file_path [default=%default]") help="Set gain [default=%(default)r]")
parser.add_option( parser.add_argument(
"", "--if-gain", dest="if_gain", type="eng_float", default=eng_notation.num_to_str(satnogs.not_set_rx_if_gain), "--iq-file-path", dest="iq_file_path", type=str, default='/tmp/iq.dat',
help="Set if_gain [default=%default]") help="Set iq_file_path [default=%(default)r]")
parser.add_option( parser.add_argument(
"", "--iq-file-path", dest="iq_file_path", type="string", default='/tmp/iq.dat', "--lo-offset", dest="lo_offset", type=eng_float, default="100.0k",
help="Set iq_file_path [default=%default]") help="Set lo_offset [default=%(default)r]")
parser.add_option( parser.add_argument(
"", "--lo-offset", dest="lo_offset", type="eng_float", default=eng_notation.num_to_str(100e3), "--rigctl-port", dest="rigctl_port", type=intx, default=4532,
help="Set lo_offset [default=%default]") help="Set rigctl_port [default=%(default)r]")
parser.add_option( parser.add_argument(
"", "--ppm", dest="ppm", type="intx", default=0, "--rx-freq", dest="rx_freq", type=eng_float, default="100.0M",
help="Set ppm [default=%default]") help="Set rx_freq [default=%(default)r]")
parser.add_option( parser.add_argument(
"", "--rf-gain", dest="rf_gain", type="eng_float", default=eng_notation.num_to_str(satnogs.not_set_rx_rf_gain), "--samp-rate-rx", dest="samp_rate_rx", type=eng_float, default="0.0",
help="Set rf_gain [default=%default]") help="Set Device Sampling rate [default=%(default)r]")
parser.add_option( parser.add_argument(
"", "--rigctl-port", dest="rigctl_port", type="intx", default=4532, "--soapy-rx-device", dest="soapy_rx_device", type=str, default='driver=invalid',
help="Set rigctl_port [default=%default]") help="Set soapy_rx_device [default=%(default)r]")
parser.add_option( parser.add_argument(
"", "--rx-freq", dest="rx_freq", type="eng_float", default=eng_notation.num_to_str(100e6), "--udp-IP", dest="udp_IP", type=str, default='127.0.0.1',
help="Set rx_freq [default=%default]") help="Set udp_IP [default=%(default)r]")
parser.add_option( parser.add_argument(
"", "--rx-sdr-device", dest="rx_sdr_device", type="string", default='usrpb200', "--udp-port", dest="udp_port", type=intx, default=16887,
help="Set rx_sdr_device [default=%default]") help="Set udp_port [default=%(default)r]")
parser.add_option( parser.add_argument(
"", "--samp-rate-rx", dest="samp_rate_rx", type="eng_float", default=eng_notation.num_to_str(satnogs.not_set_samp_rate_rx), "--waterfall-file-path", dest="waterfall_file_path", type=str, default='/tmp/waterfall.dat',
help="Set samp_rate_rx [default=%default]") help="Set waterfall_file_path [default=%(default)r]")
parser.add_option(
"", "--udp-IP", dest="udp_IP", type="string", default='127.0.0.1',
help="Set udp_IP [default=%default]")
parser.add_option(
"", "--udp-port", dest="udp_port", type="intx", default=16887,
help="Set udp_port [default=%default]")
parser.add_option(
"", "--waterfall-file-path", dest="waterfall_file_path", type="string", default='/tmp/waterfall.dat',
help="Set waterfall_file_path [default=%default]")
return parser return parser
def main(top_block_cls=satnogs_amsat_fox_duv_decoder, options=None): def main(top_block_cls=satnogs_amsat_fox_duv_decoder, options=None):
if options is None: if options is None:
options, _ = argument_parser().parse_args() options = argument_parser().parse_args()
tb = top_block_cls(antenna=options.antenna, bw=options.bw, decoded_data_file_path=options.decoded_data_file_path, dev_args=options.dev_args, doppler_correction_per_sec=options.doppler_correction_per_sec, enable_iq_dump=options.enable_iq_dump, file_path=options.file_path, gain=options.gain, iq_file_path=options.iq_file_path, lo_offset=options.lo_offset, rigctl_port=options.rigctl_port, rx_freq=options.rx_freq, samp_rate_rx=options.samp_rate_rx, soapy_rx_device=options.soapy_rx_device, udp_IP=options.udp_IP, udp_port=options.udp_port, waterfall_file_path=options.waterfall_file_path)
def sig_handler(sig=None, frame=None):
tb.stop()
tb.wait()
sys.exit(0)
signal.signal(signal.SIGINT, sig_handler)
signal.signal(signal.SIGTERM, sig_handler)
tb = top_block_cls(antenna=options.antenna, baudrate=options.baudrate, bb_gain=options.bb_gain, decoded_data_file_path=options.decoded_data_file_path, dev_args=options.dev_args, doppler_correction_per_sec=options.doppler_correction_per_sec, enable_iq_dump=options.enable_iq_dump, file_path=options.file_path, if_gain=options.if_gain, iq_file_path=options.iq_file_path, lo_offset=options.lo_offset, ppm=options.ppm, rf_gain=options.rf_gain, rigctl_port=options.rigctl_port, rx_freq=options.rx_freq, rx_sdr_device=options.rx_sdr_device, samp_rate_rx=options.samp_rate_rx, udp_IP=options.udp_IP, udp_port=options.udp_port, waterfall_file_path=options.waterfall_file_path)
tb.start() tb.start()
tb.wait() tb.wait()