Merge pull request #178 from darksidelemm/testing

Switch to dfm09mod, report APRS station position using a position report.
pull/181/head
Mark Jessop 2019-05-18 16:50:37 +09:30 zatwierdzone przez GitHub
commit b86a8c63b3
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
12 zmienionych plików z 254 dodań i 194 usunięć

Wyświetl plik

@ -17,7 +17,7 @@ except ImportError:
# MINOR - New sonde type support, other fairly big changes that may result in telemetry or config file incompatability issus.
# PATCH - Small changes, or minor feature additions.
__version__ = "1.1.0"
__version__ = "1.1.1-beta"
# Global Variables

Wyświetl plik

@ -153,7 +153,7 @@ def telemetry_to_aprs_position(sonde_data, object_name="<id>", aprs_comment="BOM
def generate_station_object(callsign, lat, lon, comment="radiosonde_auto_rx SondeGate v<version>", icon='/r'):
def generate_station_object(callsign, lat, lon, comment="radiosonde_auto_rx SondeGate v<version>", icon='/r', position_report=False):
''' Generate a station object '''
# Pad or limit the station callsign to 9 characters, if it is to long or short.
@ -192,7 +192,13 @@ def generate_station_object(callsign, lat, lon, comment="radiosonde_auto_rx Sond
_aprs_comment = _aprs_comment.replace('<version>', auto_rx_version)
# Generate output string
out_str = ";%s*%sh%s%s%s%s%s" % (callsign, _aprs_timestamp, lat_str, icon[0], lon_str, icon[1], _aprs_comment)
if position_report:
# Produce a position report with no timestamp, as per page 32 of http://www.aprs.org/doc/APRS101.PDF
out_str = "!%s%s%s%s%s" % (lat_str, icon[0], lon_str, icon[1], _aprs_comment)
else:
# Produce an object string
out_str = ";%s*%sh%s%s%s%s%s" % (callsign, _aprs_timestamp, lat_str, icon[0], lon_str, icon[1], _aprs_comment)
return out_str
@ -388,15 +394,16 @@ class APRSUploader(object):
''' Send a station position beacon into APRS-IS '''
if self.station_beacon['enabled']:
# Generate the station position packet
# Note - this is generated as an APRS object.
# Note - this is now generated as an APRS position report, for radiosondy.info compatability.
_packet = generate_station_object(self.aprs_callsign,
self.station_beacon['position'][0],
self.station_beacon['position'][1],
self.station_beacon['comment'],
self.station_beacon['icon'])
self.station_beacon['icon'],
position_report=True)
# Send the packet
self.aprsis_upload(self.aprs_callsign, _packet, igate=False)
# Send the packet as an iGated packet.
self.aprsis_upload(self.aprs_callsign, _packet, igate=True)
self.last_user_position_upload = time.time()

Wyświetl plik

@ -325,7 +325,7 @@ class SondeDecoder(object):
decode_cmd += " tee decode_%s.wav |" % str(self.device_idx)
# DFM decoder
decode_cmd += "./dfm09ecc -vv --ecc --json --dist --auto 2>/dev/null"
decode_cmd += "./dfm09mod -vv --ecc --json --dist --auto 2>/dev/null"
elif self.sonde_type == "M10":
# M10 Sondes
@ -400,7 +400,7 @@ class SondeDecoder(object):
_upper = int(0.475 * _sdr_rate)
_freq = int(self.sonde_freq - _sdr_rate*_offset)
decode_cmd = "%s %s-p %d -d %s %s-M raw -s %d -f %d 2>/dev/null |" % (self.sdr_fm, bias_option, int(self.ppm), str(self.device_idx), gain_param, _sdr_rate, _freq)
decode_cmd = "%s %s-p %d -d %s %s-M raw -F9 -s %d -f %d 2>/dev/null |" % (self.sdr_fm, bias_option, int(self.ppm), str(self.device_idx), gain_param, _sdr_rate, _freq)
# Add in tee command to save IQ to disk if debugging is enabled.
if self.save_decode_iq:
decode_cmd += " tee decode_IQ_%s.bin |" % str(self.device_idx)
@ -449,7 +449,7 @@ class SondeDecoder(object):
_upper = int(0.475 * _sdr_rate)
_freq = int(self.sonde_freq - _sdr_rate*_offset)
decode_cmd = "%s %s-p %d -d %s %s-M raw -s %d -f %d 2>/dev/null |" % (self.sdr_fm, bias_option, int(self.ppm), str(self.device_idx), gain_param, _sdr_rate, _freq)
decode_cmd = "%s %s-p %d -d %s %s-M raw -F9 -s %d -f %d 2>/dev/null |" % (self.sdr_fm, bias_option, int(self.ppm), str(self.device_idx), gain_param, _sdr_rate, _freq)
# Add in tee command to save IQ to disk if debugging is enabled.
if self.save_decode_iq:
@ -466,9 +466,6 @@ class SondeDecoder(object):
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.
_sdr_rate = 50000
_baud_rate = 2500
@ -477,21 +474,21 @@ class SondeDecoder(object):
_upper = int(0.475 * _sdr_rate)
_freq = int(self.sonde_freq - _sdr_rate*_offset)
decode_cmd = "%s %s-p %d -d %s %s-M raw -s %d -f %d 2>/dev/null |" % (self.sdr_fm, bias_option, int(self.ppm), str(self.device_idx), gain_param, _sdr_rate, _freq)
decode_cmd = "%s %s-p %d -d %s %s-M raw -F9 -s %d -f %d 2>/dev/null |" % (self.sdr_fm, bias_option, int(self.ppm), str(self.device_idx), gain_param, _sdr_rate, _freq)
# Add in tee command to save IQ to disk if debugging is enabled.
if self.save_decode_iq:
decode_cmd += " tee decode_IQ_%s.bin |" % str(self.device_idx)
decode_cmd += "./fsk_demod --cs16 -b %d -u %d %s2 %d %d - - %s |" % (_lower, _upper, _stats_command_1, _sdr_rate, _baud_rate, _stats_command_2)
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 |" % (_sdr_rate, _baud_rate, _sdr_rate, _sdr_rate)
# 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"
decode_cmd += "./dfm09mod -vv --ecc --json --dist --auto --bin 2>/dev/null"
elif self.sonde_type == "M10":
# M10 Sondes
@ -504,7 +501,7 @@ class SondeDecoder(object):
_upper = int(0.475 * _sdr_rate)
_freq = int(self.sonde_freq - _sdr_rate*_offset)
decode_cmd = "%s %s-p %d -d %s %s-M raw -s %d -f %d 2>/dev/null |" % (self.sdr_fm, bias_option, int(self.ppm), str(self.device_idx), gain_param, _sdr_rate, _freq)
decode_cmd = "%s %s-p %d -d %s %s-M raw -F9 -s %d -f %d 2>/dev/null |" % (self.sdr_fm, bias_option, int(self.ppm), str(self.device_idx), gain_param, _sdr_rate, _freq)
# Add in tee command to save IQ to disk if debugging is enabled.
if self.save_decode_iq:
@ -605,7 +602,8 @@ class SondeDecoder(object):
def handle_decoder_line(self, data):
""" Handle a line of output from the decoder subprocess.
""" Handle a line of output from the decoder subprocess, and pass it onto all of the telemetry
exporters.
Args:
data (str, bytearray): One line of text output from the decoder subprocess.
@ -613,9 +611,6 @@ class SondeDecoder(object):
Returns:
bool: True if the line was decoded to a JSON object correctly, False otherwise.
"""
# Don't even try and decode lines which don't start with a '{'
# These may be other output from the decoder, which we shouldn't try to parse.
# Catch 'bad' first characters.
try:
@ -623,7 +618,9 @@ class SondeDecoder(object):
except UnicodeDecodeError:
return
# Catch non-JSON object lines.
# Don't even try and decode lines which don't start with a '{'
# These may be other output from the decoder, which we shouldn't try to parse.
# TODO: Perhaps we should add the option to log the raw data output from the decoders?
if data.decode('ascii')[0] != '{':
return
@ -651,12 +648,15 @@ class SondeDecoder(object):
_telemetry[_field] = self.DECODER_OPTIONAL_FIELDS[_field]
# Check for an encrypted flag (this indicates a sonde that we cannot decode telemetry from.)
# Check for an encrypted flag, and check if it is set.
# Currently encrypted == true indicates an encrypted RS41-SGM. There's no point
# trying to decode this, so we close the decoder at this point.
if 'encrypted' in _telemetry:
self.log_error("Radiosonde %s has encrypted telemetry (possible RS41-SGM)! We cannot decode this, closing decoder." % _telemetry['id'])
self.exit_state = "Encrypted"
self.decoder_running = False
return False
if _telemetry['encrypted']:
self.log_error("Radiosonde %s has encrypted telemetry (Possible encrypted RS41-SGM)! We cannot decode this, closing decoder." % _telemetry['id'])
self.exit_state = "Encrypted"
self.decoder_running = False
return False
# Check the datetime field is parseable.
try:
@ -665,8 +665,15 @@ class SondeDecoder(object):
self.log_error("Invalid date/time in telemetry dict - %s (Sonde may not have GPS lock)" % str(e))
return False
# Add in the sonde frequency and type fields.
_telemetry['type'] = self.sonde_type
# Add in the sonde type field.
# If we are provided with a subtype field from the decoder, use this,
# otherwise use the detected sonde type.
if 'subtype' in _telemetry:
_telemetry['type'] = _telemetry['subtype']
else:
_telemetry['type'] = self.sonde_type
# TODO: Use frequency data provided by the decoder, if available.
_telemetry['freq_float'] = self.sonde_freq/1e6
_telemetry['freq'] = "%.3f MHz" % (self.sonde_freq/1e6)
@ -684,11 +691,12 @@ class SondeDecoder(object):
# Check we have GPS lock.
if _telemetry['sats'] < 4:
# No GPS lock means an invalid time, which means we can't accurately calculate a unique ID.
# We need to quit at this point before the telemetry processing gos any further.
self.log_error("iMet sonde has no GPS lock - discarding frame.")
return False
# Fix up the time.
_telemetry['datetime_dt'] = imet_fix_datetime(_telemetry['datetime'])
_telemetry['datetime_dt'] = fix_datetime(_telemetry['datetime'])
# Generate a unique ID based on the power-on time and frequency, as iMet sondes don't send one.
# Latch this ID and re-use it for the entire decode run.
if self.imet_id == None:

Wyświetl plik

@ -9,13 +9,11 @@ import datetime
import hashlib
from dateutil.parser import parse
#
# iMet Radiosonde Functions
#
def imet_fix_datetime(datetime_str, local_dt_str = None):
def fix_datetime(datetime_str, local_dt_str = None):
'''
Given a HH:MM:SS string from an iMet telemetry sentence, produce a complete timestamp, using the current system time as a guide for the date.
Given a HH:MM:SS string from a telemetry sentence, produce a complete timestamp, using the current system time as a guide for the date.
'''
if local_dt_str is None:
@ -50,6 +48,10 @@ def imet_fix_datetime(datetime_str, local_dt_str = None):
return _imet_dt
#
# iMet Radiosonde Functions
#
def imet_unique_id(telemetry, custom=""):
'''
Generate a 'unique' imet radiosonde ID based on the power-on time, frequency, and an optional location code.

Wyświetl plik

@ -30,7 +30,7 @@ except ImportError:
# List of binaries we check for on startup
REQUIRED_RS_UTILS = ['dft_detect', 'dfm09ecc', 'm10', 'imet1rs_dft', 'rs41mod', 'rs92mod', 'fsk_demod']
REQUIRED_RS_UTILS = ['dft_detect', 'dfm09mod', 'm10', 'imet1rs_dft', 'rs41mod', 'rs92mod', 'fsk_demod']
def check_rs_utils():
""" Check the required RS decoder binaries exist

Wyświetl plik

@ -21,11 +21,10 @@ cd ../demod/mod/
gcc -c demod_mod.c -w
gcc -c bch_ecc_mod.c -w
gcc rs41mod.c demod_mod.o bch_ecc_mod.o -lm -o rs41mod -w
# Holding off on using the new DFM decoder until the DFM17/15 ID issue is resolved.
#gcc dfm09mod.c demod_mod.o -lm -o dfm09mod -w
gcc dfm09mod.c demod_mod.o -lm -o dfm09mod -w
gcc rs92mod.c demod_mod.o bch_ecc_mod.o -lm -o rs92mod -w
#gcc lms6mod.c demod_mod.o bch_ecc_mod.o -lm -o lms6mod -w
#gcc m10mod.c demod_mod.o -lm -o m10mod -w
gcc m10mod.c demod_mod.o -lm -o m10mod -w
# Build M10 decoder
@ -57,7 +56,8 @@ cp ../utils/fsk_demod .
cp ../imet/imet1rs_dft .
cp ../demod/mod/rs41mod .
#cp ../demod/mod/dfm09mod .
cp ../demod/mod/dfm09mod .
cp ../demod/mod/m10mod .
cp ../demod/mod/rs92mod .
#cp ../demod/mod/lms6mod .

Wyświetl plik

@ -191,7 +191,8 @@ station_beacon_commment = radiosonde_auto_rx SondeGate v<version>
# Note that the two characters that define the icon need to be concatenated. Examples:
# Antenna Tower = /r
# House with Yagi = /y
station_beacon_icon = /r
# Satellite Dish = /` (This is required if you want to show up on radiosondy.info's station list.)
station_beacon_icon = /`

Wyświetl plik

@ -115,50 +115,49 @@ processing_type = {
# # FSK-DEMOD DECODING
# #
# # RS41 Decoding
# 'rs41_fsk_demod': {
# # Shift up to ~24 khz, and then pass into fsk_demod.
# 'demod' : "| csdr shift_addition_cc 0.25 2>/dev/null | csdr convert_f_s16 | ../fsk_demod --cs16 -b 1 -u 45000 --stats=100 2 96000 4800 - - 2>stats.txt |",
'rs41_fsk_demod': {
# Shift up to ~24 khz, and then pass into fsk_demod.
'demod' : "| csdr shift_addition_cc 0.25 2>/dev/null | csdr convert_f_s16 | ../fsk_demod --cs16 -b 1 -u 45000 --stats=100 2 96000 4800 - - 2>stats.txt |",
# # Decode using rs41ecc
# 'decode': "../rs41mod --ecc --ptu --crc --bin 2>/dev/null",
# # Count the number of telemetry lines.
# "post_process" : " | grep 00000 | wc -l",
# 'files' : "./generated/rs41*"
# },
# # # RS92 Decoding
# 'rs92_fsk_demod': {
# # Not currently working - need to resolve segfault in dfk_demod when using 96 kHz Fs ans 2400 Rb
# # Shift up to ~24 khz, and then pass into fsk_demod.
# 'demod' : "| csdr shift_addition_cc 0.25 2>/dev/null | csdr convert_f_s16 | ../fsk_demod --cs16 -b 1 -u 45000 --stats=100 2 96000 4800 - - 2>stats.txt | python ./bit_to_samples.py 48000 4800 | sox -t raw -r 48k -e unsigned-integer -b 8 -c 1 - -r 48000 -b 8 -t wav - 2>/dev/null|",
# Decode using rs41ecc
'decode': "../rs41mod --ecc --ptu --crc --bin 2>/dev/null",
# Count the number of telemetry lines.
"post_process" : " | grep 00000 | wc -l",
'files' : "./generated/rs41*"
},
# # RS92 Decoding
'rs92_fsk_demod': {
# Not currently working - need to resolve segfault in dfk_demod when using 96 kHz Fs ans 2400 Rb
# Shift up to ~24 khz, and then pass into fsk_demod.
'demod' : "| csdr shift_addition_cc 0.25 2>/dev/null | csdr convert_f_s16 | ../fsk_demod --cs16 -b 1 -u 45000 --stats=100 2 96000 4800 - - 2>stats.txt | python ./bit_to_samples.py 48000 4800 | sox -t raw -r 48k -e unsigned-integer -b 8 -c 1 - -r 48000 -b 8 -t wav - 2>/dev/null|",
# # Decode using rs41ecc
# 'decode': "../rs92mod -vx -v --crc --ecc --vel 2>/dev/null",
# # Count the number of telemetry lines.
# "post_process" : " | grep M2513116 | wc -l",
# 'files' : "./generated/rs92*"
# },
# 'm10_fsk_demod': {
# # Not currently working due to weird baud rate (9614). Doesnt work even with fractional resampling (slow down signal to make it appear to be 9600 baud).
# # Shift up to ~24 khz, and then pass into fsk_demod.
# 'demod' : "| csdr shift_addition_cc 0.25 2>/dev/null | csdr convert_f_s16 | ../tsrc - - 1.0016666 -c | ../fsk_demod --cs16 -b 1 -u 45000 --stats=100 2 96160 9616 - - 2>stats.txt | python ./bit_to_samples.py 57696 9616 | sox -t raw -r 57696 -e unsigned-integer -b 8 -c 1 - -r 57696 -b 8 -t wav - 2>/dev/null| ",
# 'decode': "../m10 -b -b2 2>/dev/null",
# # Count the number of telemetry lines.
# "post_process" : "| wc -l",
# 'files' : "./generated/m10*"
# },
# Decode using rs41ecc
'decode': "../rs92mod -vx -v --crc --ecc --vel 2>/dev/null",
# Count the number of telemetry lines.
"post_process" : " | grep M2513116 | wc -l",
'files' : "./generated/rs92*"
},
'm10_fsk_demod': {
# Not currently working due to weird baud rate (9614). Doesnt work even with fractional resampling (slow down signal to make it appear to be 9600 baud).
# Shift up to ~24 khz, and then pass into fsk_demod.
'demod' : "| csdr shift_addition_cc 0.25 2>/dev/null | csdr convert_f_s16 | ../tsrc - - 1.0016666 -c | ../fsk_demod --cs16 -b 1 -u 45000 --stats=100 2 96160 9616 - - 2>stats.txt | python ./bit_to_samples.py 57696 9616 | sox -t raw -r 57696 -e unsigned-integer -b 8 -c 1 - -r 57696 -b 8 -t wav - 2>/dev/null| ",
'decode': "../m10 -b -b2 2>/dev/null",
# Count the number of telemetry lines.
"post_process" : "| wc -l",
'files' : "./generated/m10*"
},
'dfm_fsk_demod': {
# cat ./generated/dfm09_96k_float_15.0dB.bin | csdr shift_addition_cc 0.25000 2>/dev/null | csdr convert_f_s16 |
#./tsrc - - 1.041666 | ../fsk_demod --cs16 -b 1 -u 45000 2 100000 2500 - - 2>/dev/null |
#python ./bit_to_samples.py 50000 2500 | sox -t raw -r 50k -e unsigned-integer -b 8 -c 1 - -r 50000 -b 8 -t wav - 2>/dev/null|
#../dfm09ecc -vv --json --dist --auto
# 'dfm_fsk_demod': {
# # cat ./generated/dfm09_96k_float_15.0dB.bin | csdr shift_addition_cc 0.25000 2>/dev/null | csdr convert_f_s16 |
# #./tsrc - - 1.041666 | ../fsk_demod --cs16 -b 1 -u 45000 2 100000 2500 - - 2>/dev/null |
# #python ./bit_to_samples.py 50000 2500 | sox -t raw -r 50k -e unsigned-integer -b 8 -c 1 - -r 50000 -b 8 -t wav - 2>/dev/null|
# #../dfm09ecc -vv --json --dist --auto
# 'demod': '| csdr shift_addition_cc 0.25000 2>/dev/null | csdr convert_f_s16 | ../tsrc - - 1.041666 | ../fsk_demod --cs16 -b 1 -u 45000 --stats=100 2 100000 2500 - - 2>stats.txt | python ./bit_to_samples.py 50000 2500 | sox -t raw -r 50k -e unsigned-integer -b 8 -c 1 - -r 50000 -b 8 -t wav - 2>/dev/null| ',
# 'decode': '../dfm09ecc -vv --json --dist --auto 2>/dev/null',
# "post_process" : " | grep frame | wc -l", # ECC
# #"post_process" : "| grep -o '\[OK\]' | wc -l", # No ECC
# 'files' : "./generated/dfm*.bin"
# }
'demod': '| csdr shift_addition_cc 0.25000 2>/dev/null | csdr convert_f_s16 | ../tsrc - - 1.041666 | ../fsk_demod --cs16 -b 1 -u 45000 --stats=100 2 100000 2500 - - 2>stats.txt |',#' python ./bit_to_samples.py 50000 2500 | sox -t raw -r 50k -e unsigned-integer -b 8 -c 1 - -r 50000 -b 8 -t wav - 2>/dev/null| ',
'decode': '../dfm09mod -vv --json --dist --auto --bin 2>/dev/null',
"post_process" : " | grep frame | wc -l", # ECC
#"post_process" : "| grep -o '\[OK\]' | wc -l", # No ECC
'files' : "./generated/dfm*.bin"
}
}
@ -183,67 +182,67 @@ processing_type = {
_sample_fs = 96000.0 # Sample rate of input. Always 96k at the moment.
# RS41
_fm_rate = 15000
# Calculate the necessary conversions
_rtlfm_oversampling = 8.0 # Viproz's hacked rtl_fm oversamples by 8x.
_shift = -2.0*_fm_rate/_sample_fs # rtl_fm tunes 'up' by rate*2, so we need to shift the signal down by this amount.
# # RS41
# _fm_rate = 15000
# # Calculate the necessary conversions
# _rtlfm_oversampling = 8.0 # Viproz's hacked rtl_fm oversamples by 8x.
# _shift = -2.0*_fm_rate/_sample_fs # rtl_fm tunes 'up' by rate*2, so we need to shift the signal down by this amount.
_resample = (_fm_rate*_rtlfm_oversampling)/_sample_fs
# _resample = (_fm_rate*_rtlfm_oversampling)/_sample_fs
if _resample != 1.0:
# We will need to resample.
_resample_command = "csdr convert_f_s16 | ./tsrc - - %.4f | csdr convert_s16_f |" % _resample
_shift = (-2.0*_fm_rate)/(_sample_fs*_resample)
else:
_resample_command = ""
# if _resample != 1.0:
# # We will need to resample.
# _resample_command = "csdr convert_f_s16 | ./tsrc - - %.4f | csdr convert_s16_f |" % _resample
# _shift = (-2.0*_fm_rate)/(_sample_fs*_resample)
# else:
# _resample_command = ""
_demod_command = "| %s csdr shift_addition_cc %.5f 2>/dev/null | csdr convert_f_u8 |" % (_resample_command, _shift)
_demod_command += " ./rtl_fm_stdin -M fm -f 401000000 -F9 -s %d 2>/dev/null|" % (int(_fm_rate))
_demod_command += " sox -t raw -r %d -e s -b 16 -c 1 - -r 48000 -b 8 -t wav - highpass 20 lowpass 2600 2>/dev/null |" % int(_fm_rate)
# _demod_command = "| %s csdr shift_addition_cc %.5f 2>/dev/null | csdr convert_f_u8 |" % (_resample_command, _shift)
# _demod_command += " ./rtl_fm_stdin -M fm -f 401000000 -F9 -s %d 2>/dev/null|" % (int(_fm_rate))
# _demod_command += " sox -t raw -r %d -e s -b 16 -c 1 - -r 48000 -b 8 -t wav - highpass 20 lowpass 2600 2>/dev/null |" % int(_fm_rate)
processing_type['rs41_rtlfm'] = {
# Shift signal to -30 kHz, resample to 120 kHz, (8x 15 khz output rate), then convert to u8 before passing into rtl_fm_stdin.
# Currently using a timeout to kill rtl_fm as it doesnt notice the end of the incoming samples.
'demod': _demod_command,
# Decode using rs41ecc
'decode': "../rs41mod --ptu --crc --ecc2 2>/dev/null",
# Count the number of telemetry lines.
"post_process" : " | grep 00000 | wc -l",
'files' : "./generated/rs41*.bin"
}
# processing_type['rs41_rtlfm'] = {
# # Shift signal to -30 kHz, resample to 120 kHz, (8x 15 khz output rate), then convert to u8 before passing into rtl_fm_stdin.
# # Currently using a timeout to kill rtl_fm as it doesnt notice the end of the incoming samples.
# 'demod': _demod_command,
# # Decode using rs41ecc
# 'decode': "../rs41mod --ptu --crc --ecc2 2>/dev/null",
# # Count the number of telemetry lines.
# "post_process" : " | grep 00000 | wc -l",
# 'files' : "./generated/rs41*.bin"
# }
# RS92
_fm_rate = 12000
# Calculate the necessary conversions
_rtlfm_oversampling = 8.0 # Viproz's hacked rtl_fm oversamples by 8x.
_shift = -2.0*_fm_rate/_sample_fs # rtl_fm tunes 'up' by rate*2, so we need to shift the signal down by this amount.
# # RS92
# _fm_rate = 12000
# # Calculate the necessary conversions
# _rtlfm_oversampling = 8.0 # Viproz's hacked rtl_fm oversamples by 8x.
# _shift = -2.0*_fm_rate/_sample_fs # rtl_fm tunes 'up' by rate*2, so we need to shift the signal down by this amount.
_resample = (_fm_rate*_rtlfm_oversampling)/_sample_fs
# _resample = (_fm_rate*_rtlfm_oversampling)/_sample_fs
if _resample != 1.0:
# We will need to resample.
_resample_command = "csdr convert_f_s16 | ./tsrc - - %.4f | csdr convert_s16_f |" % _resample
_shift = (-2.0*_fm_rate)/(_sample_fs*_resample)
else:
_resample_command = ""
# if _resample != 1.0:
# # We will need to resample.
# _resample_command = "csdr convert_f_s16 | ./tsrc - - %.4f | csdr convert_s16_f |" % _resample
# _shift = (-2.0*_fm_rate)/(_sample_fs*_resample)
# else:
# _resample_command = ""
_demod_command = "| %s csdr shift_addition_cc %.5f 2>/dev/null | csdr convert_f_u8 |" % (_resample_command, _shift)
_demod_command += " ./rtl_fm_stdin -M fm -f 401000000 -F9 -s %d 2>/dev/null|" % (int(_fm_rate))
_demod_command += " sox -t raw -r %d -e s -b 16 -c 1 - -r 48000 -b 8 -t wav - highpass 20 2>/dev/null |" % int(_fm_rate)
# _demod_command = "| %s csdr shift_addition_cc %.5f 2>/dev/null | csdr convert_f_u8 |" % (_resample_command, _shift)
# _demod_command += " ./rtl_fm_stdin -M fm -f 401000000 -F9 -s %d 2>/dev/null|" % (int(_fm_rate))
# _demod_command += " sox -t raw -r %d -e s -b 16 -c 1 - -r 48000 -b 8 -t wav - highpass 20 2>/dev/null |" % int(_fm_rate)
processing_type['rs92_rtlfm'] = {
'demod': _demod_command,
# Decode using rs92ecc
'decode': "../rs92mod -vx -v --crc --ecc --vel 2>/dev/null",
#'decode': "../rs92ecc -vx -v --crc --ecc -r --vel 2>/dev/null", # For measuring No-ECC performance
# Count the number of telemetry lines.
"post_process" : " | grep M2513116 | wc -l",
#"post_process" : " | grep \"errors: 0\" | wc -l",
'files' : "./generated/rs92*.bin"
}
# processing_type['rs92_rtlfm'] = {
# 'demod': _demod_command,
# # Decode using rs92ecc
# 'decode': "../rs92mod -vx -v --crc --ecc --vel 2>/dev/null",
# #'decode': "../rs92ecc -vx -v --crc --ecc -r --vel 2>/dev/null", # For measuring No-ECC performance
# # Count the number of telemetry lines.
# "post_process" : " | grep M2513116 | wc -l",
# #"post_process" : " | grep \"errors: 0\" | wc -l",
# 'files' : "./generated/rs92*.bin"
# }
# # RS92-NGP (wider bandwidth)
@ -277,62 +276,62 @@ processing_type['rs92_rtlfm'] = {
# 'files' : "./generated/rsngp*.bin"
# }
# DFM
_fm_rate = 15000 # Match what's in autorx.decode
# Calculate the necessary conversions
_rtlfm_oversampling = 8.0 # Viproz's hacked rtl_fm oversamples by 8x.
_shift = -2.0*_fm_rate/_sample_fs # rtl_fm tunes 'up' by rate*2, so we need to shift the signal down by this amount.
# # DFM
# _fm_rate = 15000 # Match what's in autorx.decode
# # Calculate the necessary conversions
# _rtlfm_oversampling = 8.0 # Viproz's hacked rtl_fm oversamples by 8x.
# _shift = -2.0*_fm_rate/_sample_fs # rtl_fm tunes 'up' by rate*2, so we need to shift the signal down by this amount.
_resample = (_fm_rate*_rtlfm_oversampling)/_sample_fs
# _resample = (_fm_rate*_rtlfm_oversampling)/_sample_fs
if _resample != 1.0:
# We will need to resample.
_resample_command = "csdr convert_f_s16 | ./tsrc - - %.4f | csdr convert_s16_f |" % _resample
_shift = (-2.0*_fm_rate)/(_sample_fs*_resample)
else:
_resample_command = ""
# For some reason the DFM sample breaks type conversion - multiplying it by 0.9 seems to fix it.
_demod_command = "| csdr gain_ff 0.90 | %s csdr shift_addition_cc %.5f 2>/dev/null | csdr convert_f_u8 |" % (_resample_command, _shift)
_demod_command += " ./rtl_fm_stdin -M fm -f 401000000 -F9 -s %d 2>/dev/null|" % (int(_fm_rate))
_demod_command += " sox -t raw -r %d -e s -b 16 -c 1 - -r 48000 -b 8 -t wav - highpass 20 lowpass 2000 2>/dev/null |" % int(_fm_rate)
# if _resample != 1.0:
# # We will need to resample.
# _resample_command = "csdr convert_f_s16 | ./tsrc - - %.4f | csdr convert_s16_f |" % _resample
# _shift = (-2.0*_fm_rate)/(_sample_fs*_resample)
# else:
# _resample_command = ""
# # For some reason the DFM sample breaks type conversion - multiplying it by 0.9 seems to fix it.
# _demod_command = "| csdr gain_ff 0.90 | %s csdr shift_addition_cc %.5f 2>/dev/null | csdr convert_f_u8 |" % (_resample_command, _shift)
# _demod_command += " ./rtl_fm_stdin -M fm -f 401000000 -F9 -s %d 2>/dev/null|" % (int(_fm_rate))
# _demod_command += " sox -t raw -r %d -e s -b 16 -c 1 - -r 48000 -b 8 -t wav - highpass 20 lowpass 2000 2>/dev/null |" % int(_fm_rate)
processing_type['dfm_rtlfm'] = {
'demod': _demod_command,
'decode': "../dfm09ecc -vv --json --dist --auto 2>/dev/null", # ECC
#'decode': "../dfm09ecc -vv --ecc -r --auto 2>/dev/null", # No-ECC
# Count the number of telemetry lines.
"post_process" : " | grep frame | wc -l", # ECC
#"post_process" : "| grep -o '\[OK\]' | wc -l", # No ECC
'files' : "./generated/dfm*.bin"
}
# processing_type['dfm_rtlfm'] = {
# 'demod': _demod_command,
# 'decode': "../dfm09mod -vv --json --dist --auto 2>/dev/null", # ECC
# #'decode': "../dfm09ecc -vv --ecc -r --auto 2>/dev/null", # No-ECC
# # Count the number of telemetry lines.
# "post_process" : " | grep frame | wc -l", # ECC
# #"post_process" : "| grep -o '\[OK\]' | wc -l", # No ECC
# 'files' : "./generated/dfm*.bin"
# }
# M10
_fm_rate = 22000
# Calculate the necessary conversions
_rtlfm_oversampling = 8.0 # Viproz's hacked rtl_fm oversamples by 8x.
_shift = -2.0*_fm_rate/_sample_fs # rtl_fm tunes 'up' by rate*2, so we need to shift the signal down by this amount.
# # M10
# _fm_rate = 22000
# # Calculate the necessary conversions
# _rtlfm_oversampling = 8.0 # Viproz's hacked rtl_fm oversamples by 8x.
# _shift = -2.0*_fm_rate/_sample_fs # rtl_fm tunes 'up' by rate*2, so we need to shift the signal down by this amount.
_resample = (_fm_rate*_rtlfm_oversampling)/_sample_fs
# _resample = (_fm_rate*_rtlfm_oversampling)/_sample_fs
if _resample != 1.0:
# We will need to resample.
_resample_command = "csdr convert_f_s16 | ./tsrc - - %.4f | csdr convert_s16_f |" % _resample
_shift = (-2.0*_fm_rate)/(_sample_fs*_resample)
else:
_resample_command = ""
# if _resample != 1.0:
# # We will need to resample.
# _resample_command = "csdr convert_f_s16 | ./tsrc - - %.4f | csdr convert_s16_f |" % _resample
# _shift = (-2.0*_fm_rate)/(_sample_fs*_resample)
# else:
# _resample_command = ""
_demod_command = "| %s csdr shift_addition_cc %.5f 2>/dev/null | csdr convert_f_u8 |" % (_resample_command, _shift)
_demod_command += " ./rtl_fm_stdin -M fm -f 401000000 -F9 -s %d 2>/dev/null|" % (int(_fm_rate))
_demod_command += " sox -t raw -r %d -e s -b 16 -c 1 - -r 48000 -b 8 -t wav - highpass 20 2>/dev/null |" % int(_fm_rate)
# _demod_command = "| %s csdr shift_addition_cc %.5f 2>/dev/null | csdr convert_f_u8 |" % (_resample_command, _shift)
# _demod_command += " ./rtl_fm_stdin -M fm -f 401000000 -F9 -s %d 2>/dev/null|" % (int(_fm_rate))
# _demod_command += " sox -t raw -r %d -e s -b 16 -c 1 - -r 48000 -b 8 -t wav - highpass 20 2>/dev/null |" % int(_fm_rate)
processing_type['m10_rtlfm'] = {
'demod': _demod_command,
'decode': "../m10 -b -b2 2>/dev/null",
# Count the number of telemetry lines.
"post_process" : "| wc -l",
'files' : "./generated/m10*.bin"
}
# processing_type['m10_rtlfm'] = {
# 'demod': _demod_command,
# 'decode': "../m10 -b -b2 2>/dev/null",
# # Count the number of telemetry lines.
# "post_process" : "| wc -l",
# 'files' : "./generated/m10*.bin"
# }
# # iMet
# _fm_rate = 15000

Wyświetl plik

@ -362,9 +362,7 @@ int f32buf_sample(dsp_t *dsp, int inv) {
float xneu, xalt;
float complex z, w, z0;
//static float complex z0; //= 1.0;
double gain = 0.8;
int n;
double t = dsp->sample_in / (double)dsp->sr;
@ -377,14 +375,14 @@ int f32buf_sample(dsp_t *dsp, int inv) {
z0 = dsp->rot_iqbuf[(dsp->sample_in-1 + dsp->N_IQBUF) % dsp->N_IQBUF];
w = z * conj(z0);
s = gain * carg(w)/M_PI;
//z0 = z;
dsp->rot_iqbuf[dsp->sample_in % dsp->N_IQBUF] = z;
/* //if (rs_type==rs41) get_SNR(dsp);
// rs41, constant amplitude, avg/filter
s = 0.0;
for (n = 0; n < dsp->sps; n++) s += cabs(dsp->rot_iqbuf[(dsp->sample_in - n + dsp->N_IQBUF) % dsp->N_IQBUF]);
s /= (float)n;
int n;
double r = 0.0;
for (n = 0; n < dsp->sps; n++) r += cabs(dsp->rot_iqbuf[(dsp->sample_in - n + dsp->N_IQBUF) % dsp->N_IQBUF]);
r /= (float)n;
*/
if (dsp->opt_iq >= 2)
@ -394,10 +392,41 @@ int f32buf_sample(dsp_t *dsp, int inv) {
double f1 = -dsp->h*dsp->sr/(2*dsp->sps);
double f2 = -f1;
float complex X0 = 0;
float complex X = 0;
int n = dsp->sps;
double tn = (dsp->sample_in-n) / (double)dsp->sr;
//t = dsp->sample_in / (double)dsp->sr;
//z = dsp->rot_iqbuf[dsp->sample_in % dsp->N_IQBUF];
z0 = dsp->rot_iqbuf[(dsp->sample_in-n + dsp->N_IQBUF) % dsp->N_IQBUF];
// f1
X0 = z0 * cexp(-tn*2*M_PI*f1*I); // alt
X = z * cexp(-t *2*M_PI*f1*I); // neu
dsp->F1sum += X - X0;
// f2
X0 = z0 * cexp(-tn*2*M_PI*f2*I); // alt
X = z * cexp(-t *2*M_PI*f2*I); // neu
dsp->F2sum += X - X0;
xbit = cabs(dsp->F2sum) - cabs(dsp->F1sum);
s = xbit / dsp->sps;
}
else if (0 && dsp->opt_iq >= 4)
{
double xbit = 0.0;
//float complex xi = cexp(+I*M_PI*dsp->h/dsp->sps);
double f1 = -dsp->h*dsp->sr/(2*dsp->sps);
double f2 = -f1;
float complex X1 = 0;
float complex X2 = 0;
n = dsp->sps;
int n = dsp->sps;
while (n > 0) {
n--;
t = -n / (double)dsp->sr;
@ -415,7 +444,7 @@ int f32buf_sample(dsp_t *dsp, int inv) {
if (f32read_sample(dsp, &s) == EOF) return EOF;
}
if (inv) s = -s; // swap IQ?
if (inv) s = -s;
dsp->bufs[dsp->sample_in % dsp->M] = s - dsp->dc_ofs;
xneu = dsp->bufs[(dsp->sample_in ) % dsp->M];

Wyświetl plik

@ -67,6 +67,8 @@ typedef struct {
int N_IQBUF;
float complex *raw_iqbuf;
float complex *rot_iqbuf;
float complex F1sum;
float complex F2sum;
//
char *rawbits;

Wyświetl plik

@ -192,6 +192,10 @@ frame[0x3+2*n] = PRN_(n+1)
frame[0x4+2*n] = signal level (float32 -> i8-byte level)
*/
/*
M10 w/ Sierra Wireless Airprime X1110
-> Trimble Copernicus II
*/
#define stdFLEN 0x64 // pos[0]=0x64
@ -255,9 +259,13 @@ static int get_GPSweek(gpx_t *gpx) {
}
gpsweek = (gpsweek_bytes[0] << 8) + gpsweek_bytes[1];
gpx->week = gpsweek;
if (gpsweek < 0 || gpsweek > 3000) return -1;
if (gpsweek > 4000) return -1;
// Trimble Copernicus II WNRO (AirPrime XM1110 OK)
if (gpsweek < 1304 /*2005-01-02*/ ) gpsweek += 1024;
gpx->week = gpsweek;
return 0;
}

Wyświetl plik

@ -100,7 +100,7 @@ typedef struct {
ui16_t conf_kt; // kill timer (sec)
ui16_t conf_bt; // burst timer (sec)
ui8_t conf_bk; // burst kill
ui16_t conf_cd; // kill countdown (sec) (kt or bt)
ui8_t conf_cd; // kill countdown (sec) (kt or bt)
char rstyp[9]; // RS41-SG, RS41-SGP
int aux;
char xdata[XDATA_LEN+16]; // xdata: aux_str1#aux_str2 ...
@ -975,13 +975,17 @@ static int get_Calconf(gpx_t *gpx, int out) {
if (calfr == 0x31) { // 0x59..0x5A
ui16_t bt = gpx->frame[pos_CalData+7] + (gpx->frame[pos_CalData+8] << 8); // burst timer (short?)
// fw >= 0x4ef5: default=[88 77]=0x7788sec=510min
if (out && gpx->option.vbs && bt != 0x0000 && gpx->conf_bk) fprintf(stdout, ": bt %.1fmin ", bt/60.0);
if (out && bt != 0x0000 &&
(gpx->option.vbs == 3 || gpx->option.vbs && gpx->conf_bk)
) fprintf(stdout, ": bt %.1fmin ", bt/60.0);
gpx->conf_bt = bt;
}
if (calfr == 0x32) {
ui16_t cd = gpx->frame[pos_CalData+1] + (gpx->frame[pos_CalData+2] << 8); // countdown (bt or kt) (short?)
if (out && gpx->option.vbs && cd != 0xFFFF) fprintf(stdout, ": cd %.1fmin ", cd/60.0);
if (out && cd != 0xFFFF &&
(gpx->option.vbs == 3 || gpx->option.vbs && (gpx->conf_bk || gpx->conf_kt != 0xFFFF))
) fprintf(stdout, ": cd %.1fmin ", cd/60.0);
gpx->conf_cd = cd;
}
@ -1209,8 +1213,8 @@ static int print_position(gpx_t *gpx, int ec) {
// Print out telemetry data as JSON
if ((!err && !err1 && !err3) || (!err && encrypted)) { // frame-nb/id && gps-time && gps-position (crc-)ok; 3 CRCs, RS not needed
// eigentlich GPS, d.h. UTC = GPS - 18sec (ab 1.1.2017)
fprintf(stdout, "{ \"frame\": %d, \"id\": \"%s\", \"datetime\": \"%04d-%02d-%02dT%02d:%02d:%06.3fZ\", \"lat\": %.5f, \"lon\": %.5f, \"alt\": %.5f, \"vel_h\": %.5f, \"heading\": %.5f, \"vel_v\": %.5f, \"sats\": %d, \"bt\": %d",
gpx->frnr, gpx->id, gpx->jahr, gpx->monat, gpx->tag, gpx->std, gpx->min, gpx->sek, gpx->lat, gpx->lon, gpx->alt, gpx->vH, gpx->vD, gpx->vV, gpx->numSV, gpx->conf_cd );
fprintf(stdout, "{ \"frame\": %d, \"id\": \"%s\", \"datetime\": \"%04d-%02d-%02dT%02d:%02d:%06.3fZ\", \"lat\": %.5f, \"lon\": %.5f, \"alt\": %.5f, \"vel_h\": %.5f, \"heading\": %.5f, \"vel_v\": %.5f, \"sats\": %d",
gpx->frnr, gpx->id, gpx->jahr, gpx->monat, gpx->tag, gpx->std, gpx->min, gpx->sek, gpx->lat, gpx->lon, gpx->alt, gpx->vH, gpx->vD, gpx->vV, gpx->numSV );
if (gpx->option.ptu && !err0 && gpx->T > -273.0) {
fprintf(stdout, ", \"temp\": %.1f", gpx->T );
}