kopia lustrzana https://github.com/projecthorus/radiosonde_auto_rx
Add experimental decoders.
rodzic
26b7b8ccc0
commit
1ba539650b
|
@ -201,7 +201,13 @@ class SondeDecoder(object):
|
|||
raise TypeError("Supplied exporter has incorrect type.")
|
||||
|
||||
# Generate the decoder command.
|
||||
self.decoder_command = self.generate_decoder_command()
|
||||
if self.experimental_decoder:
|
||||
self.decoder_command = self.generate_decoder_command_experimental()
|
||||
# TODO: Split the experimental decoder subprocess into two processed, and
|
||||
# split out the status data from fsk_demod so we can use it.
|
||||
else:
|
||||
self.decoder_command = self.generate_decoder_command()
|
||||
|
||||
|
||||
if self.decoder_command is None:
|
||||
self.log_error("Could not generate decoder command. Not starting decoder.")
|
||||
|
@ -217,14 +223,150 @@ class SondeDecoder(object):
|
|||
|
||||
|
||||
def generate_decoder_command(self):
|
||||
""" Generate the shell command which runs the relevant radiosonde decoder.
|
||||
""" Generate the shell command which runs the relevant radiosonde decoder - Standard decoders.
|
||||
|
||||
This is where support for new sonde types can be added.s
|
||||
|
||||
Returns:
|
||||
str/None: The shell command which will be run in the decoder thread, or none if a valid decoder could not be found.
|
||||
"""
|
||||
# Common options to rtl_fm
|
||||
|
||||
# Add a -T option if bias is enabled
|
||||
bias_option = "-T " if self.bias else ""
|
||||
|
||||
# Add a gain parameter if we have been provided one.
|
||||
if self.gain != -1:
|
||||
gain_param = '-g %.1f ' % self.gain
|
||||
else:
|
||||
gain_param = ''
|
||||
|
||||
|
||||
if self.sonde_type == "RS41":
|
||||
# RS41 Decoder command.
|
||||
# rtl_fm -p 0 -g -1 -M fm -F9 -s 15k -f 405500000 | sox -t raw -r 15k -e s -b 16 -c 1 - -r 48000 -b 8 -t wav - lowpass 2600 2>/dev/null | ./rs41ecc --crc --ecc --ptu
|
||||
# Note: Have removed a 'highpass 20' filter from the sox line, will need to re-evaluate if adding that is useful in the future.
|
||||
decode_cmd = "%s %s-p %d -d %s %s-M fm -F9 -s 15k -f %d 2>/dev/null | " % (self.sdr_fm, bias_option, int(self.ppm), str(self.device_idx), gain_param, self.sonde_freq)
|
||||
|
||||
# If selected by the user, we can add a highpass filter into the sox command. This helps handle up to about 5ppm of receiver drift
|
||||
# before performance becomes significantly degraded. By default this is off, as it is not required with TCXO RTLSDRs, and actually
|
||||
# slightly degrades performance.
|
||||
if self.rs41_drift_tweak:
|
||||
_highpass = "highpass 20 "
|
||||
else:
|
||||
_highpass = ""
|
||||
|
||||
decode_cmd += "sox -t raw -r 15k -e s -b 16 -c 1 - -r 48000 -b 8 -t wav - %slowpass 2600 2>/dev/null | " % _highpass
|
||||
|
||||
# Add in tee command to save audio to disk if debugging is enabled.
|
||||
if self.save_decode_audio:
|
||||
decode_cmd += " tee decode_%s.wav |" % str(self.device_idx)
|
||||
|
||||
decode_cmd += "./rs41mod --ptu --json 2>/dev/null"
|
||||
|
||||
elif self.sonde_type == "RS92":
|
||||
# Decoding a RS92 requires either an ephemeris or an almanac file.
|
||||
# If we have been supplied an ephemeris file, we will attempt to use it, otherwise
|
||||
# we will try and download one.
|
||||
if self.rs92_ephemeris == None:
|
||||
# If no ephemeris data defined, attempt to download it.
|
||||
# get_ephemeris will either return the saved file name, or None.
|
||||
self.rs92_ephemeris = get_ephemeris(destination="ephemeris.dat")
|
||||
|
||||
# If ephemeris is still None, then we failed to download the ephemeris data.
|
||||
# Try and grab the almanac data instead
|
||||
if self.rs92_ephemeris == None:
|
||||
self.log_error("Could not obtain ephemeris data, trying to download an almanac.")
|
||||
almanac = get_almanac(destination="almanac.txt")
|
||||
if almanac == None:
|
||||
# We probably don't have an internet connection. Bomb out, since we can't do much with the sonde telemetry without an almanac!
|
||||
self.log_error("Could not obtain GPS ephemeris or almanac data.")
|
||||
return None
|
||||
else:
|
||||
_rs92_gps_data = "-a almanac.txt --gpsepoch 2" # Note - This will need to be updated in... 19 years.
|
||||
else:
|
||||
_rs92_gps_data = "-e ephemeris.dat"
|
||||
else:
|
||||
_rs92_gps_data = "-e %s" % self.rs92_ephemeris
|
||||
|
||||
# Adjust the receive bandwidth based on the band the scanning is occuring in.
|
||||
if self.sonde_freq < 1000e6:
|
||||
# 400-406 MHz sondes - use a 12 kHz FM demod bandwidth.
|
||||
_rx_bw = 12000
|
||||
else:
|
||||
# 1680 MHz sondes - use a 28 kHz FM demod bandwidth.
|
||||
# NOTE: This is a first-pass of this bandwidth, and may need to be optimized.
|
||||
_rx_bw = 28000
|
||||
|
||||
# Now construct the decoder command.
|
||||
# rtl_fm -p 0 -g 26.0 -M fm -F9 -s 12k -f 400500000 | sox -t raw -r 12k -e s -b 16 -c 1 - -r 48000 -b 8 -t wav - highpass 20 lowpass 2500 2>/dev/null | ./rs92ecc -vx -v --crc --ecc --vel -e ephemeris.dat
|
||||
decode_cmd = "%s %s-p %d -d %s %s-M fm -F9 -s %d -f %d 2>/dev/null |" % (self.sdr_fm, bias_option, int(self.ppm), str(self.device_idx), gain_param, _rx_bw, self.sonde_freq)
|
||||
decode_cmd += "sox -t raw -r %d -e s -b 16 -c 1 - -r 48000 -b 8 -t wav - lowpass 2500 highpass 20 2>/dev/null |" % _rx_bw
|
||||
|
||||
# Add in tee command to save audio to disk if debugging is enabled.
|
||||
if self.save_decode_audio:
|
||||
decode_cmd += " tee decode_%s.wav |" % str(self.device_idx)
|
||||
|
||||
decode_cmd += "./rs92mod -vx -v --crc --ecc --vel --json %s 2>/dev/null" % _rs92_gps_data
|
||||
|
||||
elif self.sonde_type == "DFM":
|
||||
# DFM06/DFM09 Sondes.
|
||||
# As of 2019-02-10, dfm09ecc auto-detects if the signal is inverted,
|
||||
# so we don't need to specify an invert flag.
|
||||
# 2019-02-27: Added the --dist flag, which should reduce bad positions a bit.
|
||||
|
||||
# Note: Have removed a 'highpass 20' filter from the sox line, will need to re-evaluate if adding that is useful in the future.
|
||||
decode_cmd = "%s %s-p %d -d %s %s-M fm -F9 -s 15k -f %d 2>/dev/null |" % (self.sdr_fm, bias_option, int(self.ppm), str(self.device_idx), gain_param, self.sonde_freq)
|
||||
decode_cmd += "sox -t raw -r 15k -e s -b 16 -c 1 - -r 48000 -b 8 -t wav - highpass 20 lowpass 2000 2>/dev/null |"
|
||||
|
||||
# Add in tee command to save audio to disk if debugging is enabled.
|
||||
if self.save_decode_audio:
|
||||
decode_cmd += " tee decode_%s.wav |" % str(self.device_idx)
|
||||
|
||||
# DFM decoder
|
||||
decode_cmd += "./dfm09ecc -vv --ecc --json --dist --auto 2>/dev/null"
|
||||
|
||||
elif self.sonde_type == "M10":
|
||||
# M10 Sondes
|
||||
|
||||
decode_cmd = "%s %s-p %d -d %s %s-M fm -F9 -s 22k -f %d 2>/dev/null |" % (self.sdr_fm, bias_option, int(self.ppm), str(self.device_idx), gain_param, self.sonde_freq)
|
||||
decode_cmd += "sox -t raw -r 22k -e s -b 16 -c 1 - -r 48000 -b 8 -t wav - highpass 20 2>/dev/null |"
|
||||
|
||||
# Add in tee command to save audio to disk if debugging is enabled.
|
||||
if self.save_decode_audio:
|
||||
decode_cmd += " tee decode_%s.wav |" % str(self.device_idx)
|
||||
|
||||
# M10 decoder
|
||||
decode_cmd += "./m10 -b -b2 2>/dev/null"
|
||||
|
||||
elif self.sonde_type == "iMet":
|
||||
# iMet-4 Sondes
|
||||
|
||||
decode_cmd = "%s %s-p %d -d %s %s-M fm -F9 -s 15k -f %d 2>/dev/null |" % (self.sdr_fm, bias_option, int(self.ppm), str(self.device_idx), gain_param, self.sonde_freq)
|
||||
decode_cmd += "sox -t raw -r 15k -e s -b 16 -c 1 - -r 48000 -b 8 -t wav - highpass 20 2>/dev/null |"
|
||||
|
||||
# Add in tee command to save audio to disk if debugging is enabled.
|
||||
if self.save_decode_audio:
|
||||
decode_cmd += " tee decode_%s.wav |" % str(self.device_idx)
|
||||
|
||||
# iMet-4 (IMET1RS) decoder
|
||||
decode_cmd += "./imet1rs_dft --json 2>/dev/null"
|
||||
|
||||
else:
|
||||
return None
|
||||
|
||||
return decode_cmd
|
||||
|
||||
|
||||
|
||||
def generate_decoder_command_experimental(self):
|
||||
""" Generate the shell command which runs the relevant radiosonde decoder - Experimental Decoders
|
||||
|
||||
Returns:
|
||||
str/None: The shell command which will be run in the decoder thread, or none if a valid decoder could not be found.
|
||||
|
||||
"""
|
||||
|
||||
self.log_info("Using experimental decoder chain.")
|
||||
# Common options to rtl_fm
|
||||
|
||||
# Add a -T option if bias is enabled
|
||||
|
@ -286,12 +428,13 @@ class SondeDecoder(object):
|
|||
|
||||
|
||||
if self.sonde_freq > 1000e6:
|
||||
# Use a higher IQ rate for 1680 MHz sondes, at the expensive of some CPU usage.
|
||||
# Use a higher IQ rate for 1680 MHz sondes, at the expense of some CPU usage.
|
||||
_sdr_rate = 96000
|
||||
else:
|
||||
# On 400 MHz, use 48 khz - RS92s dont drift far enough to need any more than this.
|
||||
_sdr_rate = 48000
|
||||
|
||||
_output_rate = 48000
|
||||
_baud_rate = 4800
|
||||
_offset = 0.25 # Place the sonde frequency in the centre of the passband.
|
||||
_lower = int(0.025 * _sdr_rate) # Limit the frequency estimation window to not include the passband edges.
|
||||
|
@ -305,7 +448,7 @@ class SondeDecoder(object):
|
|||
decode_cmd += " tee decode_IQ_%s.bin |" % str(self.device_idx)
|
||||
|
||||
decode_cmd += "./fsk_demod --cs16 -b %d -u %d --stats=%d 2 %d %d - - 2>stats.txt " % (_lower, _upper, _stats_rate, _sdr_rate, _baud_rate)
|
||||
decode_cmd += "| python ./test/bit_to_samples.py %d %d | sox -t raw -r %d -e unsigned-integer -b 8 -c 1 - -r %d -b 8 -t wav - 2>/dev/null|" % (_sdr_rate, _baud_rate, _sdr_rate, _sdr_rate)
|
||||
decode_cmd += "| python ./test/bit_to_samples.py %d %d | sox -t raw -r %d -e unsigned-integer -b 8 -c 1 - -r %d -b 8 -t wav - 2>/dev/null|" % (_output_rate, _baud_rate, _output_rate, _output_rate)
|
||||
|
||||
# Add in tee command to save audio to disk if debugging is enabled.
|
||||
if self.save_decode_audio:
|
||||
|
@ -344,6 +487,8 @@ class SondeDecoder(object):
|
|||
|
||||
elif self.sonde_type == "M10":
|
||||
# M10 Sondes
|
||||
# These have a 'weird' baud rate, and as fsk_demod requires the input sample rate to be an integer multiple of the baud rate,
|
||||
# our required sample rate is correspondingly weird!
|
||||
_sdr_rate = 48080
|
||||
_baud_rate = 9616
|
||||
_offset = 0.25 # Place the sonde frequency in the centre of the passband.
|
||||
|
@ -382,7 +527,6 @@ class SondeDecoder(object):
|
|||
decode_cmd += "./imet1rs_dft --json 2>/dev/null"
|
||||
|
||||
else:
|
||||
# Should never get here.
|
||||
return None
|
||||
|
||||
return decode_cmd
|
||||
|
|
|
@ -289,4 +289,5 @@ void M10GtopParser::printFrame() {
|
|||
"Gtop", frame, getSerialNumber().c_str(), getdxlSerialNumber().c_str(), getYear(), getMonth(), getDay(), getHours(), getMinutes(), getSeconds(), getLatitude(), getLongitude(),
|
||||
getAltitude(), getHorizontalSpeed(), getDirection(), getVerticalSpeed()/*, getTemperature()*/, correctCRC);
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
|
|
@ -469,6 +469,7 @@ void M10TrimbleParser::printFrame() {
|
|||
auxstr.c_str(), getSatellites(), getLatitude(), getLongitude(),
|
||||
getAltitude(), getHorizontalSpeed(), getDirection(), getVerticalSpeed(), getTemperature(), getBatteryLevel(), correctCRC);
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Ładowanie…
Reference in New Issue