Skip to content

Instantly share code, notes, and snippets.

@linuxsocist
Last active March 23, 2018 07:07
Show Gist options
  • Save linuxsocist/d262ec7eeaad9f8af3d48bba640ce83b to your computer and use it in GitHub Desktop.
Save linuxsocist/d262ec7eeaad9f8af3d48bba640ce83b to your computer and use it in GitHub Desktop.
A collection of scripts I use for capturing and decoding LRPT signals automatically. (See comment for basic setup instructions).
#!/bin/bash
sFile=$(ls -tr S-files/*.s | tail -n 1)
outFile=$(echo ${sFile/.s/})
echo "====================" >> decode-log
./medet $sFile $outFile -r 65 -g 65 -b 64 -q >> decode-log
date +%Y-%m-%d_%H%M >> decode-log
exit 1
#!/usr/bin/fish
function process_list
cat METEOR-M-2-passes.txt | egrep -e "20" | awk '($2 < 11 ) && ($8 > 25 ) {print $1" "$2" "$6" "$7" "$8}' > meteor-list
end
function set_dates
set NUM 1
set LINE (wc -l meteor-list | awk '{print $1}')
while [ $NUM -le $LINE ]
set PASS (cat meteor-list | sed -n ''$NUM'p')
set DATE (echo $PASS | awk '{print $1}' | tr '/' '-')
set AOS (echo $PASS | awk '{print $2}' | cut -c1-5)
set AOSSEC (echo $PASS | awk '{print $2}' | cut -c7-8)
set LOS (echo $PASS | awk '{print $3}' | cut -c1-5)
set LOSSEC (echo $PASS | awk '{print $3}' | cut -c7-8)
echo "sleep $AOSSEC; ./meteorrecsh" | at $AOS $DATE 2>> set_times
echo "sleep $LOSSEC; ./meteorreckill" | at $LOS $DATE 2>> set_times
echo "sleep $LOSSEC; ./autodecode" | at $LOS $DATE 2>> set_times
printf "Set to record on $DATE at $AOS:$AOSSEC and end at $LOS:$LOSSEC\n"
set NUM (math "$NUM + 1")
#sleep 1
end
end
process_list
set_dates
#!/usr/bin/python
##################################################
# Gnuradio Python Flow Graph
# Title: LRPT Soft-Symbol Receiver
# Author: Martin Blaho (mod by Raydel Abreu)
# Description: LRPT Soft-Symbol Receiver
# Generated: Fri Sep 26 09:35:14 2014
##################################################
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 import wxgui
from gnuradio.eng_option import eng_option
from gnuradio.fft import window
from gnuradio.filter import firdes
from gnuradio.wxgui import fftsink2
from gnuradio.wxgui import forms
from gnuradio.wxgui import scopesink2
from grc_gnuradio import wxgui as grc_wxgui
from optparse import OptionParser
from time import strftime, localtime, gmtime
import math, os
import osmosdr
import wx
class meteor_qpsk_rx_rtl(grc_wxgui.top_block_gui):
def __init__(self, satellite='MeteorMN2', symb_rate=72000, gainrf=42.1, freq=137.9e6, clock_alpha=0.001, pll_alpha=0.005, decim=8, freqcorrect=62):
grc_wxgui.top_block_gui.__init__(self, title="LRPT Soft-Symbol Receiver")
_icon_path = "/usr/share/icons/hicolor/32x32/apps/gnuradio-grc.png"
self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY))
##################################################
# Parameters
##################################################
self.satellite = satellite
self.symb_rate = symb_rate
self.gainrf = gainrf
self.freq = freq
self.clock_alpha = clock_alpha
self.pll_alpha = pll_alpha
self.decim = decim
self.freqcorrect = freqcorrect
##################################################
# Variables
##################################################
self.samp_rate_rtl = samp_rate_rtl = 1024000
self.symb_rate_tb = symb_rate_tb = symb_rate
self.samp_rate = samp_rate = samp_rate_rtl/decim
self.variable_constellation_0 = variable_constellation_0 = digital.constellation_calcdist(([-1-1j, -1+1j, 1+1j, 1-1j]), ([0, 1, 3, 2]), 4, 1).base()
self.sps = sps = (samp_rate*1.0)/(symb_rate_tb*1.0)
self.satellite_text = satellite_text = satellite
self.samp_rate_st = samp_rate_st = samp_rate
self.pll_alpha_sl = pll_alpha_sl = pll_alpha
self.if_gain = if_gain = 20
self.gainrf_tb = gainrf_tb = gainrf
self.freqcorrect_tb = freqcorrect_tb = freqcorrect
self.freq_tb = freq_tb = freq
self.fileTime = fileTime = strftime("%Y%m%d_%H%M%S", localtime())
if symb_rate == 72000:
self.fileTime = "meteor_LRPT_"+fileTime
self.clock_alpha_sl = clock_alpha_sl = clock_alpha
self.bb_gain = bb_gain = 10
##################################################
# Blocks
##################################################
self.rx_ntb = self.rx_ntb = wx.Notebook(self.GetWin(), style=wx.NB_TOP)
self.rx_ntb.AddPage(grc_wxgui.Panel(self.rx_ntb), " Receiver")
self.rx_ntb.AddPage(grc_wxgui.Panel(self.rx_ntb), "PLL demodulator and Clock sync")
self.rx_ntb.AddPage(grc_wxgui.Panel(self.rx_ntb), "Output")
self.Add(self.rx_ntb)
_pll_alpha_sl_sizer = wx.BoxSizer(wx.VERTICAL)
self._pll_alpha_sl_text_box = forms.text_box(
parent=self.rx_ntb.GetPage(1).GetWin(),
sizer=_pll_alpha_sl_sizer,
value=self.pll_alpha_sl,
callback=self.set_pll_alpha_sl,
label="PLL Alpha",
converter=forms.float_converter(),
proportion=0,
)
self._pll_alpha_sl_slider = forms.slider(
parent=self.rx_ntb.GetPage(1).GetWin(),
sizer=_pll_alpha_sl_sizer,
value=self.pll_alpha_sl,
callback=self.set_pll_alpha_sl,
minimum=0.001,
maximum=0.1,
num_steps=100,
style=wx.SL_HORIZONTAL,
cast=float,
proportion=1,
)
self.rx_ntb.GetPage(1).GridAdd(_pll_alpha_sl_sizer, 1, 0, 1, 1)
_if_gain_sizer = wx.BoxSizer(wx.VERTICAL)
self._if_gain_text_box = forms.text_box(
parent=self.rx_ntb.GetPage(0).GetWin(),
sizer=_if_gain_sizer,
value=self.if_gain,
callback=self.set_if_gain,
label="IF_gain",
converter=forms.float_converter(),
proportion=0,
)
self._if_gain_slider = forms.slider(
parent=self.rx_ntb.GetPage(0).GetWin(),
sizer=_if_gain_sizer,
value=self.if_gain,
callback=self.set_if_gain,
minimum=0.5,
maximum=50,
num_steps=1000,
style=wx.SL_HORIZONTAL,
cast=float,
proportion=1,
)
self.rx_ntb.GetPage(0).Add(_if_gain_sizer)
self._gainrf_tb_text_box = forms.text_box(
parent=self.rx_ntb.GetPage(0).GetWin(),
value=self.gainrf_tb,
callback=self.set_gainrf_tb,
label="RF gain [dB]",
converter=forms.float_converter(),
)
self.rx_ntb.GetPage(0).GridAdd(self._gainrf_tb_text_box, 1, 2, 1, 1)
self._freqcorrect_tb_text_box = forms.text_box(
parent=self.rx_ntb.GetPage(0).GetWin(),
value=self.freqcorrect_tb,
callback=self.set_freqcorrect_tb,
label="Freq. Correct",
converter=forms.int_converter(),
)
self.rx_ntb.GetPage(0).GridAdd(self._freqcorrect_tb_text_box, 1, 3, 1, 1)
self._freq_tb_text_box = forms.text_box(
parent=self.rx_ntb.GetPage(0).GetWin(),
value=self.freq_tb,
callback=self.set_freq_tb,
label="Frequency",
converter=forms.float_converter(),
)
self.rx_ntb.GetPage(0).GridAdd(self._freq_tb_text_box, 1, 1, 1, 1)
_clock_alpha_sl_sizer = wx.BoxSizer(wx.VERTICAL)
self._clock_alpha_sl_text_box = forms.text_box(
parent=self.rx_ntb.GetPage(1).GetWin(),
sizer=_clock_alpha_sl_sizer,
value=self.clock_alpha_sl,
callback=self.set_clock_alpha_sl,
label="Clock alpha",
converter=forms.float_converter(),
proportion=0,
)
self._clock_alpha_sl_slider = forms.slider(
parent=self.rx_ntb.GetPage(1).GetWin(),
sizer=_clock_alpha_sl_sizer,
value=self.clock_alpha_sl,
callback=self.set_clock_alpha_sl,
minimum=0.001,
maximum=0.01,
num_steps=10,
style=wx.SL_HORIZONTAL,
cast=float,
proportion=1,
)
self.rx_ntb.GetPage(1).GridAdd(_clock_alpha_sl_sizer, 1, 1, 1, 1)
_bb_gain_sizer = wx.BoxSizer(wx.VERTICAL)
self._bb_gain_text_box = forms.text_box(
parent=self.rx_ntb.GetPage(0).GetWin(),
sizer=_bb_gain_sizer,
value=self.bb_gain,
callback=self.set_bb_gain,
label="BB_gain",
converter=forms.float_converter(),
proportion=0,
)
self._bb_gain_slider = forms.slider(
parent=self.rx_ntb.GetPage(0).GetWin(),
sizer=_bb_gain_sizer,
value=self.bb_gain,
callback=self.set_bb_gain,
minimum=0,
maximum=50,
num_steps=1000,
style=wx.SL_HORIZONTAL,
cast=float,
proportion=1,
)
self.rx_ntb.GetPage(0).Add(_bb_gain_sizer)
self.wxgui_scopesink2_0 = scopesink2.scope_sink_c(
self.rx_ntb.GetPage(1).GetWin(),
title="qpsk constellation",
sample_rate=symb_rate,
v_scale=0.5,
v_offset=0,
t_scale=0.5,
ac_couple=False,
xy_mode=True,
num_inputs=1,
trig_mode=wxgui.TRIG_MODE_AUTO,
y_axis_label="Counts",
)
self.rx_ntb.GetPage(1).Add(self.wxgui_scopesink2_0.win)
self.wxgui_fftsink2_0 = fftsink2.fft_sink_c(
self.rx_ntb.GetPage(0).GetWin(),
baseband_freq=freq_tb,
y_per_div=5,
y_divs=10,
ref_level=0,
ref_scale=2.0,
sample_rate=samp_rate,
fft_size=768,
fft_rate=25,
average=True,
avg_alpha=0.1,
title="filtered spectrum",
peak_hold=False,
)
self.rx_ntb.GetPage(0).Add(self.wxgui_fftsink2_0.win)
self._symb_rate_tb_text_box = forms.text_box(
parent=self.rx_ntb.GetPage(1).GetWin(),
value=self.symb_rate_tb,
callback=self.set_symb_rate_tb,
label="Symbol rate",
converter=forms.int_converter(),
)
self.rx_ntb.GetPage(1).GridAdd(self._symb_rate_tb_text_box, 1, 3, 1, 1)
self._satellite_text_static_text = forms.static_text(
parent=self.rx_ntb.GetPage(0).GetWin(),
value=self.satellite_text,
callback=self.set_satellite_text,
label="Sat ",
converter=forms.str_converter(),
)
self.rx_ntb.GetPage(0).GridAdd(self._satellite_text_static_text, 1, 0, 1, 1)
self._samp_rate_st_static_text = forms.static_text(
parent=self.rx_ntb.GetPage(0).GetWin(),
value=self.samp_rate_st,
callback=self.set_samp_rate_st,
label="Sample rate",
converter=forms.float_converter(),
)
self.rx_ntb.GetPage(0).GridAdd(self._samp_rate_st_static_text, 1, 4, 1, 1)
self.rtlsdr_source_0 = osmosdr.source( args="numchan=" + str(1) + " " + "rtl=0" )
self.rtlsdr_source_0.set_sample_rate(samp_rate_rtl)
self.rtlsdr_source_0.set_center_freq(freq_tb, 0)
self.rtlsdr_source_0.set_freq_corr(freqcorrect_tb, 0)
self.rtlsdr_source_0.set_dc_offset_mode(1, 0)
self.rtlsdr_source_0.set_iq_balance_mode(1, 0)
self.rtlsdr_source_0.set_gain_mode(False, 0)
self.rtlsdr_source_0.set_gain(gainrf_tb, 0)
self.rtlsdr_source_0.set_if_gain(if_gain, 0)
self.rtlsdr_source_0.set_bb_gain(bb_gain, 0)
self.rtlsdr_source_0.set_antenna("", 0)
self.rtlsdr_source_0.set_bandwidth(130e3, 0)
self.low_pass_filter_0 = filter.fir_filter_ccf(decim, firdes.low_pass(
1, samp_rate_rtl, samp_rate_rtl/decim/2.0, 100, firdes.WIN_RECTANGULAR, 6.76))
self._fileTime_static_text = forms.static_text(
parent=self.rx_ntb.GetPage(2).GetWin(),
value=self.fileTime,
callback=self.set_fileTime,
label="Local time of aquisition start",
converter=forms.str_converter(),
)
self.rx_ntb.GetPage(2).GridAdd(self._fileTime_static_text, 1, 1, 1, 1)
self.digital_costas_loop_cc_0 = digital.costas_loop_cc(pll_alpha_sl, 4)
self.digital_constellation_soft_decoder_cf_0 = digital.constellation_soft_decoder_cf(variable_constellation_0)
self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_cc(sps, (clock_alpha_sl**2/4.0), 0.5, clock_alpha_sl, 0.05/10)
self.blocks_throttle_0 = blocks.throttle(gr.sizeof_gr_complex*1, samp_rate,True)
self.blocks_float_to_char_0 = blocks.float_to_char(1, 127)
self.blocks_file_sink_0 = blocks.file_sink(gr.sizeof_char*1, "/home/<Your Directory Here>/S-files/"+self.fileTime+".s", False) # Change this line to reflect your own directory path.
self.blocks_file_sink_0.set_unbuffered(False)
self.analog_rail_ff_0 = analog.rail_ff(-1, 1)
self.analog_agc_xx_0 = analog.agc_cc(1000e-4, .5, 1)
self.analog_agc_xx_0.set_max_gain(4000)
##################################################
# Connections
##################################################
self.connect((self.analog_agc_xx_0, 0), (self.digital_costas_loop_cc_0, 0))
self.connect((self.digital_costas_loop_cc_0, 0), (self.digital_clock_recovery_mm_xx_0, 0))
self.connect((self.analog_agc_xx_0, 0), (self.wxgui_fftsink2_0, 0))
self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.digital_constellation_soft_decoder_cf_0, 0))
self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.wxgui_scopesink2_0, 0))
self.connect((self.digital_constellation_soft_decoder_cf_0, 0), (self.analog_rail_ff_0, 0))
self.connect((self.analog_rail_ff_0, 0), (self.blocks_float_to_char_0, 0))
self.connect((self.blocks_float_to_char_0, 0), (self.blocks_file_sink_0, 0))
self.connect((self.blocks_throttle_0, 0), (self.analog_agc_xx_0, 0))
self.connect((self.rtlsdr_source_0, 0), (self.low_pass_filter_0, 0))
self.connect((self.low_pass_filter_0, 0), (self.blocks_throttle_0, 0))
# QT sink close method reimplementation
def get_satellite(self):
return self.satellite
def set_satellite(self, satellite):
self.satellite = satellite
self.set_satellite_text(self.satellite)
def get_symb_rate(self):
return self.symb_rate
def set_symb_rate(self, symb_rate):
self.symb_rate = symb_rate
self.wxgui_scopesink2_0.set_sample_rate(self.symb_rate)
self.set_symb_rate_tb(self.symb_rate)
def get_gainrf(self):
return self.gainrf
def set_gainrf(self, gainrf):
self.gainrf = gainrf
self.set_gainrf_tb(self.gainrf)
def get_freq(self):
return self.freq
def set_freq(self, freq):
self.freq = freq
self.set_freq_tb(self.freq)
def get_clock_alpha(self):
return self.clock_alpha
def set_clock_alpha(self, clock_alpha):
self.clock_alpha = clock_alpha
self.set_clock_alpha_sl(self.clock_alpha)
def get_pll_alpha(self):
return self.pll_alpha
def set_pll_alpha(self, pll_alpha):
self.pll_alpha = pll_alpha
self.set_pll_alpha_sl(self.pll_alpha)
def get_decim(self):
return self.decim
def set_decim(self, decim):
self.decim = decim
self.set_samp_rate(self.samp_rate_rtl/self.decim)
self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.samp_rate_rtl, self.samp_rate_rtl/self.decim/2.0, 100, firdes.WIN_RECTANGULAR, 6.76))
def get_freqcorrect(self):
return self.freqcorrect
def set_freqcorrect(self, freqcorrect):
self.freqcorrect = freqcorrect
self.set_freqcorrect_tb(self.freqcorrect)
def get_samp_rate_rtl(self):
return self.samp_rate_rtl
def set_samp_rate_rtl(self, samp_rate_rtl):
self.samp_rate_rtl = samp_rate_rtl
self.set_samp_rate(self.samp_rate_rtl/self.decim)
self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.samp_rate_rtl, self.samp_rate_rtl/self.decim/2.0, 100, firdes.WIN_RECTANGULAR, 6.76))
self.rtlsdr_source_0.set_sample_rate(self.samp_rate_rtl)
def get_symb_rate_tb(self):
return self.symb_rate_tb
def set_symb_rate_tb(self, symb_rate_tb):
self.symb_rate_tb = symb_rate_tb
self.set_sps((self.samp_rate*1.0)/(self.symb_rate_tb*1.0))
self._symb_rate_tb_text_box.set_value(self.symb_rate_tb)
def get_samp_rate(self):
return self.samp_rate
def set_samp_rate(self, samp_rate):
self.samp_rate = samp_rate
self.set_sps((self.samp_rate*1.0)/(self.symb_rate_tb*1.0))
self.set_samp_rate_st(self.samp_rate)
self.blocks_throttle_0.set_sample_rate(self.samp_rate)
self.wxgui_fftsink2_0.set_sample_rate(self.samp_rate)
def get_variable_constellation_0(self):
return self.variable_constellation_0
def set_variable_constellation_0(self, variable_constellation_0):
self.variable_constellation_0 = variable_constellation_0
def get_sps(self):
return self.sps
def set_sps(self, sps):
self.sps = sps
self.digital_clock_recovery_mm_xx_0.set_omega(self.sps)
def get_satellite_text(self):
return self.satellite_text
def set_satellite_text(self, satellite_text):
self.satellite_text = satellite_text
self._satellite_text_static_text.set_value(self.satellite_text)
def get_samp_rate_st(self):
return self.samp_rate_st
def set_samp_rate_st(self, samp_rate_st):
self.samp_rate_st = samp_rate_st
self._samp_rate_st_static_text.set_value(self.samp_rate_st)
def get_pll_alpha_sl(self):
return self.pll_alpha_sl
def set_pll_alpha_sl(self, pll_alpha_sl):
self.pll_alpha_sl = pll_alpha_sl
self._pll_alpha_sl_slider.set_value(self.pll_alpha_sl)
self._pll_alpha_sl_text_box.set_value(self.pll_alpha_sl)
self.digital_costas_loop_cc_0.set_loop_bandwidth(self.pll_alpha_sl)
def get_if_gain(self):
return self.if_gain
def set_if_gain(self, if_gain):
self.if_gain = if_gain
self._if_gain_slider.set_value(self.if_gain)
self._if_gain_text_box.set_value(self.if_gain)
self.rtlsdr_source_0.set_if_gain(self.if_gain, 0)
def get_gainrf_tb(self):
return self.gainrf_tb
def set_gainrf_tb(self, gainrf_tb):
self.gainrf_tb = gainrf_tb
self._gainrf_tb_text_box.set_value(self.gainrf_tb)
self.rtlsdr_source_0.set_gain(self.gainrf_tb, 0)
def get_freqcorrect_tb(self):
return self.freqcorrect_tb
def set_freqcorrect_tb(self, freqcorrect_tb):
self.freqcorrect_tb = freqcorrect_tb
self._freqcorrect_tb_text_box.set_value(self.freqcorrect_tb)
self.rtlsdr_source_0.set_freq_corr(self.freqcorrect_tb, 0)
def get_freq_tb(self):
return self.freq_tb
def set_freq_tb(self, freq_tb):
self.freq_tb = freq_tb
self._freq_tb_text_box.set_value(self.freq_tb)
self.wxgui_fftsink2_0.set_baseband_freq(self.freq_tb)
self.rtlsdr_source_0.set_center_freq(self.freq_tb, 0)
def get_fileTime(self):
return self.fileTime
def set_fileTime(self, fileTime):
self.fileTime = fileTime
self._fileTime_static_text.set_value(self.fileTime)
def get_clock_alpha_sl(self):
return self.clock_alpha_sl
def set_clock_alpha_sl(self, clock_alpha_sl):
self.clock_alpha_sl = clock_alpha_sl
self.digital_clock_recovery_mm_xx_0.set_gain_omega((self.clock_alpha_sl**2/4.0))
self.digital_clock_recovery_mm_xx_0.set_gain_mu(self.clock_alpha_sl)
self._clock_alpha_sl_slider.set_value(self.clock_alpha_sl)
self._clock_alpha_sl_text_box.set_value(self.clock_alpha_sl)
def get_bb_gain(self):
return self.bb_gain
def set_bb_gain(self, bb_gain):
self.bb_gain = bb_gain
self.rtlsdr_source_0.set_bb_gain(self.bb_gain, 0)
self._bb_gain_slider.set_value(self.bb_gain)
self._bb_gain_text_box.set_value(self.bb_gain)
if __name__ == '__main__':
import ctypes
import sys
if sys.platform.startswith('linux'):
try:
x11 = ctypes.cdll.LoadLibrary('libX11.so')
x11.XInitThreads()
except:
print "Warning: failed to XInitThreads()"
parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
parser.add_option("", "--satellite", dest="satellite", type="string", default='MeteorMN2',
help="Set Satellite [default=%default]")
parser.add_option("", "--symb-rate", dest="symb_rate", type="intx", default=72000,
help="Set Symbol rate [default=%default]")
parser.add_option("", "--gainrf", dest="gainrf", type="eng_float", default=eng_notation.num_to_str(42.1),
help="Set Gain [default=%default]")
parser.add_option("", "--freq", dest="freq", type="eng_float", default=eng_notation.num_to_str(137.9e6),
help="Set Frequency [default=%default]")
parser.add_option("", "--clock-alpha", dest="clock_alpha", type="eng_float", default=eng_notation.num_to_str(0.001),
help="Set Clock alpha [default=%default]")
parser.add_option("", "--pll-alpha", dest="pll_alpha", type="eng_float", default=eng_notation.num_to_str(0.005),
help="Set PLL alpha [default=%default]")
parser.add_option("", "--decim", dest="decim", type="intx", default=8,
help="Set Decimation [default=%default]")
parser.add_option("", "--freqcorrect", dest="freqcorrect", type="intx", default=62,
help="Set Freq. Correct [default=%default]")
(options, args) = parser.parse_args()
if gr.enable_realtime_scheduling() != gr.RT_OK:
print "Error: failed to enable realtime scheduling."
tb = meteor_qpsk_rx_rtl(satellite=options.satellite, symb_rate=options.symb_rate, gainrf=options.gainrf, freq=options.freq, clock_alpha=options.clock_alpha, pll_alpha=options.pll_alpha, decim=options.decim, freqcorrect=options.freqcorrect)
tb.Start(True)
tb.Wait()
#!/bin/bash
kill -9 $(pgrep -l meteorrec.py | awk '{print $1}')
#!/bin/bash
env DISPLAY=:0 XAUTHORITY=~/.Xauthority ./meteorrec.py 2> /dev/null > /dev/null &
@linuxsocist
Copy link
Author

linuxsocist commented Jun 10, 2017

This requires Gpredict (for the passes list), the fish shell for the main .fish script and Artem's meteor decoder and needs to be in the "S-files" directory and can be found from here: https://github.com/artlav/meteor_decoder

As this is a work in progress you still need to create a "S-files" sub directory which the .s files and decoded bitmaps will be saved to. You will also need to edit line 276 in "meteorrec.py" to reflect your own directory for these scripts in Linux.

To get the passes list from Gpredict, right click on the Meteor-M 2 satellite and select "Future passes" then click save. You should then see a window pop up that allows you to save to a specific folder. Select the directory that contains the lrptauto.fish script and set the "File contents" option to "Summary" then save, this creates a passes list that can then be processed by the lrptauto script.

I do plan on creating a git repo in the future and rewriting the lrptauto script in bash.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment