From bd994f65cf734c719ed8d2f4245a42fa880999dc Mon Sep 17 00:00:00 2001 From: Mark Jessop Date: Mon, 23 Dec 2024 17:50:00 +1030 Subject: [PATCH 1/2] Add channel filter option for KA9Q sources, tweak decode settings for RS41 and DFM. --- README.md | 2 ++ auto_rx/autorx/__init__.py | 2 +- auto_rx/autorx/decode.py | 35 +++++++++++++++++------------ auto_rx/autorx/ka9q.py | 18 +++++++++++---- auto_rx/autorx/sdr_wrappers.py | 10 +++++---- auto_rx/station.cfg.example | 5 ++--- auto_rx/station.cfg.example.network | 11 +++++---- 7 files changed, 51 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index e7691e13..5b7ac3c6 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,8 @@ Improvements from the upstream RS codebase will be merged into this codebase whe Please consider joining the Google Group to receive updates on new software features: https://groups.google.com/forum/#!forum/radiosonde_auto_rx +We also have a channel in the SondeHub Discord server: https://sondehub.org/go/discord + ## Presentations * Linux.conf.au 2019 - https://www.youtube.com/watch?v=YBy-bXEWZeM * UKHAS Conference 2019 - [Presented via Skype](https://youtu.be/azDJmMywBgw?t=643) which had some audio issues at the start. Slides [here](https://rfhead.net/sondes/auto_rx_presentation_UKHAS2019.pdf). diff --git a/auto_rx/autorx/__init__.py b/auto_rx/autorx/__init__.py index 963f0be9..a099d74a 100644 --- a/auto_rx/autorx/__init__.py +++ b/auto_rx/autorx/__init__.py @@ -12,7 +12,7 @@ # 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.8.1-beta1" +__version__ = "1.8.1-beta2" # Global Variables diff --git a/auto_rx/autorx/decode.py b/auto_rx/autorx/decode.py index a990d4fc..81b36baf 100644 --- a/auto_rx/autorx/decode.py +++ b/auto_rx/autorx/decode.py @@ -829,9 +829,10 @@ def generate_decoder_command_experimental(self): _baud_rate = 4800 _sample_rate = 48000 # 10x Oversampling - # Limit FSK estimator window to roughly +/- 10 kHz - _lower = -10000 - _upper = 10000 + # Limit FSK estimator window to roughly +/- 5 kHz + _lower = -5000 + _upper = 5000 + demod_cmd = get_sdr_iq_cmd( sdr_type = self.sdr_type, @@ -844,14 +845,17 @@ def generate_decoder_command_experimental(self): ppm = self.ppm, gain = self.gain, bias = self.bias, - dc_block = True + dc_block = True, + channel_filter = 5000 # +/- 5 kHz channel filter. ) # Add in tee command to save IQ to disk if debugging is enabled. if self.save_decode_iq: demod_cmd += f" tee {self.save_decode_iq_path} |" - demod_cmd += "./fsk_demod --cs16 -b %d -u %d -s --stats=%d 2 %d %d - -" % ( + # Use a 4800 Hz mask estimator to better avoid adjacent sonde issues. + # Also seems to give a small performance bump. + demod_cmd += "./fsk_demod --cs16 -b %d -u %d -s --mask 4800 --stats=%d 2 %d %d - -" % ( _lower, _upper, _stats_rate, @@ -949,15 +953,16 @@ def generate_decoder_command_experimental(self): _baud_rate = 2500 _sample_rate = 50000 # 10x Oversampling - # Limit FSK estimator window to roughly +/- 10 kHz - _lower = -10000 - _upper = 10000 + # Limit FSK estimator window to roughly +/- 5 kHz + _lower = -5000 + _upper = 5000 - if (abs(403200000 - self.sonde_freq) < 20000) and (self.sdr_type == "RTLSDR"): - # Narrow up the frequency estimator window if we are close to - # the 403.2 MHz RTLSDR Spur. - _lower = -8000 - _upper = 8000 + # Un-necessary. + # if (abs(403200000 - self.sonde_freq) < 20000) and (self.sdr_type == "RTLSDR"): + # # Narrow up the frequency estimator window if we are close to + # # the 403.2 MHz RTLSDR Spur. + # _lower = -8000 + # _upper = 8000 demod_cmd = get_sdr_iq_cmd( sdr_type = self.sdr_type, @@ -970,7 +975,8 @@ def generate_decoder_command_experimental(self): ppm = self.ppm, gain = self.gain, bias = self.bias, - dc_block = True + dc_block = True, + channel_filter = 5000 ) # Add in tee command to save IQ to disk if debugging is enabled. @@ -978,6 +984,7 @@ def generate_decoder_command_experimental(self): demod_cmd += f" tee {self.save_decode_iq_path} |" # NOTE - Using inverted soft decision outputs, so DFM type detection works correctly. + # No mask estimator - DFMs seem to decode better without it! demod_cmd += "./fsk_demod --cs16 -b %d -u %d -s -i --stats=%d 2 %d %d - -" % ( _lower, _upper, diff --git a/auto_rx/autorx/ka9q.py b/auto_rx/autorx/ka9q.py index bef7e1b4..9a38731f 100644 --- a/auto_rx/autorx/ka9q.py +++ b/auto_rx/autorx/ka9q.py @@ -17,7 +17,8 @@ def ka9q_setup_channel( sdr_hostname, frequency, sample_rate, - scan + scan, + channel_filter = None ): if scan: ssrc="04" @@ -25,12 +26,20 @@ def ka9q_setup_channel( ssrc="01" # tune --samprate 48000 --frequency 404m09 --mode iq --ssrc 404090000 --radio sonde.local + + if channel_filter: + _low = int(channel_filter * -1.0) + _high = int(channel_filter) + else: + _low = int(int(sample_rate) / (-2.4)) + _high = int(int(sample_rate) / 2.4) + _cmd = ( f"{timeout_cmd()} 5 " # Add a timeout, because connections to non-existing servers block for ages f"tune " f"--samprate {int(sample_rate)} " f"--mode iq " - f"--low {int(int(sample_rate) / (-2.4))} --high {int(int(sample_rate) / 2.4)} " + f"--low {_low} --high {_high} " f"--frequency {int(frequency)} " f"--ssrc {round(frequency / 1000)}{ssrc} " f"--radio {sdr_hostname}" @@ -120,7 +129,8 @@ def ka9q_get_iq_cmd( sdr_hostname, frequency, sample_rate, - scan + scan, + channel_filter = None ): if scan: ssrc="04" @@ -128,7 +138,7 @@ def ka9q_get_iq_cmd( ssrc="01" # We need to setup a channel before we can use it! - _setup_success = ka9q_setup_channel(sdr_hostname, frequency, sample_rate, scan) + _setup_success = ka9q_setup_channel(sdr_hostname, frequency, sample_rate, scan, channel_filter) if not _setup_success: logging.critical(f"KA9Q ({sdr_hostname}) - Could not setup rx channel! Decoder will likely timeout.") diff --git a/auto_rx/autorx/sdr_wrappers.py b/auto_rx/autorx/sdr_wrappers.py index 48d25e1f..595d0491 100644 --- a/auto_rx/autorx/sdr_wrappers.py +++ b/auto_rx/autorx/sdr_wrappers.py @@ -281,7 +281,8 @@ def get_sdr_iq_cmd( sdr_hostname = "", sdr_port = 5555, ss_iq_path = "./ss_iq", - scan = False + scan = False, + channel_filter = None ): """ Get a command-line argument to get IQ (signed 16-bit) from a SDR @@ -303,7 +304,8 @@ def get_sdr_iq_cmd( Arguments for KA9Q SDR Server / SpyServer: sdr_hostname (str): Hostname of KA9Q Server sdr_port (int): Port number of KA9Q Server - scan (bool): Create unique SSRC for scan attempts + scan (bool): Create unique SSRC for scan attempts (KA9Q Only) + channel_filter (int/float): Set a high/lowpass frequency for a KA9Q channel. Arguments for SpyServer Client: ss_iq_path (str): Path to spyserver IQ client utility. @@ -361,9 +363,9 @@ def get_sdr_iq_cmd( return _cmd if sdr_type == "KA9Q": - _cmd = ka9q_get_iq_cmd(sdr_hostname, frequency, sample_rate, scan) + _cmd = ka9q_get_iq_cmd(sdr_hostname, frequency, sample_rate, scan, channel_filter) - if dc_block: + if dc_block and ("KA9Q" not in sdr_type): _cmd += _dc_remove return _cmd diff --git a/auto_rx/station.cfg.example b/auto_rx/station.cfg.example index 07d9c269..1b83246e 100644 --- a/auto_rx/station.cfg.example +++ b/auto_rx/station.cfg.example @@ -19,10 +19,9 @@ # # RTLSDR - Use one or more RTLSDRs # -# EXPERIMENTAL / NOT IMPLEMENTED options: +# Network SDR Server options: # SpyServer - Use an Airspy SpyServer # KA9Q - Use a KA9Q-Radio Server -# WARNING: These are still under development and may not work correctly. # sdr_type = RTLSDR @@ -140,7 +139,7 @@ always_decode = [] # STATION LOCATION # #################### # Used by the Sondehub Uploader, APRS Uploader, and by Rotator Control -# Lat/Lon in decimal degrees, altitude in metres. +# Lat/Lon in decimal degrees, altitude in metres (AMSL). # Note: You do not need to specify your home station accurately if you don't want to! # Feel free to use a position somewhere near your general area, that doesn't identify your home location. # diff --git a/auto_rx/station.cfg.example.network b/auto_rx/station.cfg.example.network index e5d74615..4274eb34 100644 --- a/auto_rx/station.cfg.example.network +++ b/auto_rx/station.cfg.example.network @@ -20,12 +20,11 @@ # # RTLSDR - Use one or more RTLSDRs # -# EXPERIMENTAL / NOT IMPLEMENTED options: +# Network SDR Server options: # SpyServer - Use an Airspy SpyServer # KA9Q - Use a KA9Q-Radio Server -# WARNING: These are still under development and may not work correctly. # -sdr_type = SpyServer +sdr_type = KA9Q # @@ -38,7 +37,7 @@ sdr_type = SpyServer # If SDR type is either KA9Q or SpyServer, this defines the maximum number of parallel # decoding/scan tasks. On a RPi 4, ~5 tasks are possible. # -sdr_quantity = 5 +sdr_quantity = 10 # @@ -48,7 +47,7 @@ sdr_quantity = 5 # Is using KA9Q-Radio, the hostname of the 'radio' server (e.g. sonde.local) needs to be # defined, and the port number is unused. # -sdr_hostname = localhost +sdr_hostname = sonde.local sdr_port = 5555 # @@ -141,7 +140,7 @@ always_decode = [] # STATION LOCATION # #################### # Used by the Sondehub Uploader, APRS Uploader, and by Rotator Control -# Lat/Lon in decimal degrees, altitude in metres. +# Lat/Lon in decimal degrees, altitude in metres (AMSL). # Note: You do not need to specify your home station accurately if you don't want to! # Feel free to use a position somewhere near your general area, that doesn't identify your home location. # From 705576bcc11f42eddae0d6736c955995c2be2e48 Mon Sep 17 00:00:00 2001 From: Mark Jessop Date: Wed, 25 Dec 2024 09:23:48 +1030 Subject: [PATCH 2/2] Change default minimum decoder spacing for network decoder example --- auto_rx/station.cfg.example.network | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/auto_rx/station.cfg.example.network b/auto_rx/station.cfg.example.network index 4274eb34..47dd89c2 100644 --- a/auto_rx/station.cfg.example.network +++ b/auto_rx/station.cfg.example.network @@ -549,8 +549,8 @@ scan_delay = 10 quantization = 10000 # Decoder Spacing Limit - Only start a new decoder if it is separated from an existing decoder by at least # this value (Hz). This helps avoid issues where a drifting radiosonde is detected on two adjacent channels. -# If you regularly encounter radiosondes on adjacent (10kHz) channels, then set this value to 5000. -decoder_spacing_limit = 15000 +# For Network SDR systems, we set this to a lower value than the usual default of 15 kHz, as we have better channel filtering. +decoder_spacing_limit = 5000 # Temporary Block Time (minutes) - How long to block encrypted or otherwise non-decodable sondes for. temporary_block_time = 120 # Upload when (seconds_since_utc_epoch%upload_rate) == 0. Otherwise just delay upload_rate seconds between uploads.