1
0
Fork 0
mirror of https://github.com/sdr-enthusiasts/docker-adsb-ultrafeeder.git synced 2024-10-16 05:50:44 +00:00

add autogain

This commit is contained in:
kx1t 2023-03-24 13:44:41 +01:00
parent 6055995081
commit 2c885e7da3
4 changed files with 226 additions and 4 deletions

View file

@ -30,9 +30,10 @@ version: '3.8'
services:
tar1090:
image: ghcr.io/sdr-enthusiasts/docker-adsb-all-in-one:latest
image: ghcr.io/sdr-enthusiasts/docker-adsb-ultrafeeder:latest
tty: true
container_name: adsb-all-in-one
container_name: ultrafeeder
hostname: ultrafeeder
restart: always
environment:
- TZ=Australia/Perth
@ -162,6 +163,34 @@ If you want to connect your SDR to the container, here's how to do that:
| `READSB_GAIN` | Set gain (in dB). Use `autogain` to have the container determine an appropriate gain, more on this below. | `--gain=<db>` | Max gain |
| `READSB_RTLSDR_PPM` | Set oscillator frequency correction in PPM. See [Estimating PPM](https://github.com/sdr-enthusiasts/docker-readsb-protobuf/README.MD#estimating-ppm) | `--ppm=<correction>` | Unset |
###### AutoGain for RTLSDR Devices
If you have set `READSB_GAIN=autogain`, then the system will take signal strength measurements to determine the optimal gain. The AutoGain functionality is based on a (slightly) modified version of [Wiedehopf's AutoGain](https://github.com/wiedehopf/autogain). AutoGain will only work with `rtlsdr` style receivers.
There are 2 distinct periods in which the container will attempt to figure out the gain:
* The initial period of 90 minutes, in which a measurement is taken every 5 minutes
* The subsequent period, in which a measurement is taken once every day
Please note that in order for the initial period to complete, the container must run for 90 minutes without restarting.
When taking measurements, if the percentage of "strong signals" (i.e., ADSB messages with RSSI > 3 dB) is larger than 7%, AutoGain will reduce the receiver's gain by 1 setting. Similarly, if the percentage of strong signals is smaller than 0.5%, AutoGain will increment the receiver's gain by 1 setting. When AutoGain changes the gain value, the `readsb` component of the container will restart. This may show as a disconnect / reconnected in container logs.
Although not recommended, you can change the measurement intervals and low/high cutoffs with these parameters:
| Environment Variable | Purpose | Default |
|----------------------|---------|---------|
| `READSB_AUTOGAIN_INITIAL_INTERVAL` | The measurement interval to optimize gain during the initial period of 90 minutes (in seconds) | `300` |
| `READSB_AUTOGAIN_SUBSEQUENT_INTERVAL` | The measurement interval to optimize gain during the subsequent period (in seconds) | `86400` |
| `READSB_AUTOGAIN_LOW_PCT` | If the percentage of "strong signals" (stronger than 3dBFS RSSI) is below this number, gain will be increased | `0.5` |
| `READSB_AUTOGAIN_HIGH_PCT` | If the percentage of "strong signals" (stronger than 3dBFS RSSI) is above this number, gain will be decreased | `0.5` |
If you need to reset AutoGain and start over determining the gain, you can do so with this command:
```bash
docker exec -it ultrafeeder /usr/local/bin/autogain1090 reset
```
#### Connecting to external ADSB data sources
In addition to (or instead of) connecting to a SDR or hardware device to get ADSB data, the container also supports ingesting data from a TCP port. Here are some parameters that you need to configure if you want to make this happen:
@ -326,7 +355,7 @@ All of the variables below are optional.
| `GRAPHS1090_DISK_DEVICE` | Defines which disk device (`mmc0`, `sda`, `sdc`, etc) is shown. Leave empty for default device | Unset |
| `GRAPHS1090_ETHERNET_DEVICE` | Defines which (wired) ethernet device (`eth0`, `enp0s`, etc) is shown. Leave empty for default device | Unset |
| `GRAPHS1090_WIFI_DEVICE` | Defines which (wireless) WiFi device (`wlan0`, `wlp3s0`, etc) is shown. Leave empty for default device | Unset |
| `GRAPHS1090_DISABLE` | Set to any value to disable the GRAPHS1090 web page | Unset |
| `GRAPHS1090_DISABLE` | Set to any value to disable the GRAPHS1090 web page and data collection | Unset |
| `ENABLE_AIRSPY` | Optional, set to any non-empty value if you want to enable the special AirSpy graphs. See below for additional configuration requirements | Unset |
#### Enabling UAT data

View file

@ -0,0 +1,42 @@
#!/usr/bin/with-contenv bash
# shellcheck shell=bash disable=SC2076
# Autogain routine
#
# Relevant env variables:
# READSB_GAIN: set to "autogain" to enable autogain
# READSB_AUTOGAIN_INITIAL_INTERVAL: time in seconds to run autogain during initial assessment period; 300 if omitted
# READSB_AUTOGAIN_SUBSEQUENT_INTERVAL: time in seconds to run autogain during initial assessment period; 86400 (=1 day) if omitted
# Command to restart autogain: docker exec -it tar1090 /usr/local/bin/autogain1090 reset
READSB_AUTOGAIN_INITIAL_INTERVAL="${READSB_AUTOGAIN_INITIAL_INTERVAL:-300}"
READSB_AUTOGAIN_SUBSEQUENT_INTERVAL="${READSB_AUTOGAIN_SUBSEQUENT_INTERVAL:-86400}"
if [[ "${READSB_GAIN,,}" != "autogain" ]]; then
# Autogain is not enabled, so let's do nothing forever
sleep infinity
fi
if [[ "${READSB_DEVICE_TYPE,,}" != "rtlsdr" ]] || [[ -z "${READSB_RTLSDR_DEVICE}" ]]; then
echo "[autogain] ERROR: AUTOGAIN enabled but READSB_DEVICE_TYPE is not \"rtlsdr\" or READSB_RTLSDR_DEVICE serial number not defined. Autogain disabled."
sleep infinity
fi
mkdir -p /var/globe_history/autogain
# Do special things if it's the first time AUTOGAIN is running
if [[ ! -f /var/globe_history/autogain/autogain_initialized ]]; then
# run autogain every $READSB_AUTOGAIN_INITIAL_INTERVAL minutes for 90 minutes
for (( i=0; i<$((5400/READSB_AUTOGAIN_INITIAL_INTERVAL)); i++ ))
do
sleep "$READSB_AUTOGAIN_INITIAL_INTERVAL" # sleep first to give readsb the opportunity to collect some initial data
/usr/local/bin/autogain1090 2>&1 | mawk -W Interactive '{print "[autogain] " $0}'
done
touch /var/globe_history/autogain/autogain_initialized
fi
while true
do
sleep "$READSB_AUTOGAIN_SUBSEQUENT_INTERVAL"
/usr/local/bin/autogain1090 2>&1 | mawk -W Interactive '{print "[autogain] " $0}'
done

View file

@ -229,8 +229,15 @@ if [[ -n "$READSB_DEVICE_TYPE" ]]; then
READSB_CMD+=("--device-type=$READSB_DEVICE_TYPE")
fi
# Handle "--gain"
if [[ -n "$READSB_GAIN" ]]; then
READSB_CMD+=("--gain=$READSB_GAIN")
if [[ "${READSB_GAIN,,}" == "autogain" ]] && [[ -f /var/globe_history/autogain/gain ]]; then
read -r gain < /var/globe_history/autogain/gain
READSB_CMD+=("--gain=$gain")
elif [[ -n "$READSB_GAIN" ]]; then
[[ "${READSB_GAIN,,}" == "autogain" ]] && gain="49.6" || gain="${READSB_GAIN}"
READSB_CMD+=("--gain=$gain")
fi
fi
##### RTL-SDR OPTIONS #####

144
rootfs/usr/local/bin/autogain1090 Executable file
View file

@ -0,0 +1,144 @@
#!/usr/bin/with-contenv bash
# shellcheck shell=bash
low="${READSB_AUTOGAIN_LOW_PCT:-0.5}"
high="${READSB_AUTOGAIN_HIGH_PCT:-7.0}"
ga=(0.0 0.9 1.4 2.7 3.7 7.7 8.7 12.5 14.4 15.7 16.6 19.7 20.7 22.9 25.4 28.0 29.7 32.8 33.8 36.4 37.2 38.6 40.2 42.1 43.4 43.9 44.5 48.0 49.6 -10)
tmp=/var/globe_history/autogain
mkdir -p $tmp
mkdir -p /var/globe_history/autogain
#work around stupid locale stuff
export LC_ALL=C
APP=dump1090-fa
if [[ -f /run/dump1090-fa/stats.json ]]; then
APP=dump1090-fa
elif [[ -f /run/readsb/stats.json ]]; then
APP=readsb
fi
stats=/run/$APP/stats.json
if [[ "$1" == "reset" ]]; then
echo "Reset AutoGain - restarting with initial values and initialization process"
rm -f /var/globe_history/autogain/* >/dev/null 2>&1
pkill -f "s6-supervise autogain"
exit 0
fi
if ! [[ -f $stats ]]; then echo "stats.json not found, is the decoder running?"; exit 1; fi
oldstrong=$(cat $tmp/strong 2>/dev/null)
oldtotal=$(cat $tmp/total 2>/dev/null)
if [[ -z $oldstrong ]] || [[ -z $oldtotal ]]; then
oldstrong=0
oldtotal=0
fi
if ! grep -qs total $stats | grep -qs -e strong_signals $stats; then
echo "the decoder doesn't seem to be using an rtl-sdr device, can't help with that."
exit 1
fi
# start=$(jq '.total.start' < $stats)
# end=$(jq '.total.end' < $stats)
strong=$(jq '.total.local.strong_signals' < $stats | tee $tmp/strong)
total=$(jq '.total.local.accepted | add' < $stats | tee $tmp/total)
if [[ -z $strong ]] || [[ -z $total ]]; then
echo "unrecognized format: $stats"
exit 1
fi
if ! awk "BEGIN{ exit ($total < 1000) }"; then
echo "The decoder hasn't been running long enough, wait a bit!"
exit 1
fi
if (( oldtotal > total )) || (( oldstrong > strong )) || (( oldtotal == total )); then
oldstrong=0
oldtotal=0
fi
strong=$((strong - oldstrong))
total=$((total - oldtotal))
if [[ $total == 0 ]]; then
percent=0
else
percent=$(awk "BEGIN {printf \"%.3f\", $strong * 100 / $total}")
fi
strong=$percent
if [[ $strong == "nan" ]]; then echo "Error, can't automatically adjust gain!"; exit 1; fi
# Get the gain -- updated for docker-tar1090 use by kx1t
if [[ ! -f /var/globe_history/autogain/gain ]]; then
oldgain="49.6"
echo "Initial run. Starting point for adjusting gain is $oldgain"
else
read -r oldgain < /var/globe_history/autogain/gain
oldgain="${oldgain:-49.6}" # needed for stupidity reasons
fi
gain_index=28
for i in "${!ga[@]}"; do
if ! awk "BEGIN{ exit (${oldgain} <= ${ga[$i]}) }"; then
gain_index="${i}"
break
fi
done
if ! awk "BEGIN{ exit (${oldgain} > 49.6) }"; then
gain_index=28
fi
if [[ "$oldgain" == "-10" ]]; then
gain_index=28
fi
if ! awk "BEGIN{ exit ($strong > $low) }" && ! awk "BEGIN{ exit ($strong < $high) }"; then
echo "No gain change needed, percentage of messages >-3dB is in nominal range. (${strong}%)"
exit 0
fi
if ! awk "BEGIN{ exit ($strong < $low) }" && [[ $gain_index == 28 ]]; then
echo "Gain already at maximum! (${strong}% messages >-3dB)"
exit 0
fi
if ! awk "BEGIN{ exit ($strong < $low) }"; then
gain_index=$((gain_index+1))
action=Increasing
fi
if ! awk "BEGIN{ exit ($strong > $high) }" && [[ $gain_index == 0 ]]; then
echo "Gain already at minimum! (${strong}% messages >-3dB)"
exit 0
fi
if ! awk "BEGIN{ exit ($strong > $high) }"; then
gain_index=$((gain_index-1))
action=Decreasing
fi
gain="${ga[$gain_index]}"
if [[ $gain == "" ]]; then echo "Gain already at maximum! (${strong}% messages >-3dB)"; exit 0; fi
# Set the gain -- updated for docker-tar1090 use by kx1t
echo "$gain" > /var/globe_history/autogain/gain
pkill readsb
#reset numbers
echo 0 > $tmp/strong
echo 0 > $tmp/total
echo "$action gain to $gain (${strong}% messages >-3dB)"