From 90b95f81e1edfdcd1e54b3d448b12f5ef3761ff4 Mon Sep 17 00:00:00 2001 From: Daniel Ekman Date: Thu, 12 Jan 2023 21:22:18 +0100 Subject: [PATCH] Change to multistage builder and add run scripts Signed-off-by: Daniel Ekman --- Dockerfile | 51 +++++++++++++---- docker-compose.yml | 9 +-- docker_dual_4fsk.sh | 50 +++++++++++++++++ docker_dual_rtty_4fsk.sh | 52 ++++++++++++++++++ docker_rtlsdr.sh => docker_single.sh | 26 +-------- src/CMakeLists.txt | 2 + user.env.example | 82 +++++++++++++++++++++++++--- 7 files changed, 223 insertions(+), 49 deletions(-) create mode 100755 docker_dual_4fsk.sh create mode 100755 docker_dual_rtty_4fsk.sh rename docker_rtlsdr.sh => docker_single.sh (60%) diff --git a/Dockerfile b/Dockerfile index 3d105f1..7891c90 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,19 +1,46 @@ -FROM debian:bullseye +FROM debian:bullseye as builder MAINTAINER sa2kng -ARG HOMEDIR=/home/pi/horusdemodlib -ENV PATH=${PATH}:${HOMEDIR} -RUN apt-get -y update && apt -y upgrade && apt-get -y install --no-install-recommends cmake build-essential libusb-1.0-0-dev git python3-venv python3-crcmod python3-requests python3-pip sox bc rtl-sdr libatlas-base-dev rtl-sdr && rm -rf /var/lib/apt/lists/* +RUN apt-get -y update && apt -y upgrade && apt-get -y install --no-install-recommends \ + cmake \ + build-essential \ + libusb-1.0-0-dev \ + libatlas-base-dev &&\ + rm -rf /var/lib/apt/lists/* -COPY . ${HOMEDIR} -WORKDIR ${HOMEDIR} +# install everything in /target and it will go in to / on destination image. symlink make it easier for builds to find files installed by this. +RUN mkdir -p /target/usr && rm -rf /usr/local && ln -sf /target/usr /usr/local && mkdir /target/etc -RUN cmake -B build -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release &&\ +COPY . /horusdemodlib + +RUN cd /horusdemodlib &&\ + cmake -B build -DCMAKE_INSTALL_PREFIX=/target/usr -DCMAKE_BUILD_TYPE=Release &&\ cmake --build build --target install -RUN echo '[global]\nextra-index-url=https://www.piwheels.org/simple' > /etc/pip.conf &&\ - python3 -m venv venv &&\ - . venv/bin/activate &&\ - pip install --no-cache-dir --prefer-binary -r requirements.txt &&\ - pip install --no-cache-dir --prefer-binary horusdemodlib +COPY docker_single.sh \ + docker_dual_4fsk.sh \ + docker_dual_rtty_4fsk.sh \ + /target/usr/bin/ + +# to support arm wheels +RUN echo '[global]\nextra-index-url=https://www.piwheels.org/simple' > /target/etc/pip.conf + +FROM debian:bullseye as prod +RUN apt-get -y update && apt -y upgrade && apt-get -y install --no-install-recommends \ + libusb-1.0-0 \ + python3-venv \ + python3-crcmod \ + python3-dateutil \ + python3-numpy \ + python3-requests \ + python3-pip \ + sox \ + bc \ + rtl-sdr \ + libatlas3-base &&\ + rm -rf /var/lib/apt/lists/* + +RUN pip install --system --no-cache-dir --prefer-binary horusdemodlib + +COPY --from=builder /target / CMD ["bash"] diff --git a/docker-compose.yml b/docker-compose.yml index e704999..0b449fd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,18 +1,19 @@ -version: '3.7' +version: '3.8' services: horusdemod: build: context: . + target: prod image: 'projecthorus/horusdemodlib:latest' - command: 'docker_rtlsdr.sh' - #read_only: true + #read_only: true device_cgroup_rules: - 'c 189:* rwm' env_file: - ./user.env + command: 'bash -c $${DEMODSCRIPT}' volumes: - type: 'tmpfs' target: '/tmp' - - './user.cfg:/home/pi/horusdemodlib/user.cfg' + - './user.cfg:/user.cfg' - '/dev/bus/usb:/dev/bus/usb' diff --git a/docker_dual_4fsk.sh b/docker_dual_4fsk.sh new file mode 100755 index 0000000..da13b84 --- /dev/null +++ b/docker_dual_4fsk.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash +# +# Dual Horus Binary Decoder Script +# Intended for use with Dual Launches, where both launches have 4FSK payloads closely spaced (~10 kHz) +# +# The SDR is tuned 5 kHz below the Lower 4FSK frequency, and the frequency estimators are set across the two frequencies. +# Modem statistics are sent out via a new 'MODEM_STATS' UDP broadcast message every second. +# + +# Calculate the frequency estimator limits +# Note - these are somewhat hard-coded for this dual-RX application. +MFSK1_LOWER=$(echo "$MFSK1_SIGNAL - $RXBANDWIDTH/2" | bc) +MFSK1_UPPER=$(echo "$MFSK1_SIGNAL + $RXBANDWIDTH/2" | bc) +MFSK1_CENTRE=$(echo "$RXFREQ + $MFSK1_SIGNAL" | bc) + +MFSK2_LOWER=$(echo "$MFSK2_SIGNAL - $RXBANDWIDTH/2" | bc) +MFSK2_UPPER=$(echo "$MFSK2_SIGNAL + $RXBANDWIDTH/2" | bc) +MFSK2_CENTRE=$(echo "$RXFREQ + $MFSK2_SIGNAL" | bc) + +echo "Using SDR Centre Frequency: $RXFREQ Hz." +echo "Using MFSK1 estimation range: $MFSK1_LOWER - $MFSK1_UPPER Hz" +echo "Using MFSK2 estimation range: $MFSK2_LOWER - $MFSK2_UPPER Hz" + +BIAS_SETTING="" + +if [ "$BIAS" = "1" ]; then + echo "Enabling Bias Tee." + BIAS_SETTING=" -T" +fi + +GAIN_SETTING="" +if [ "$GAIN" = "0" ]; then + echo "Using AGC." + GAIN_SETTING="" +else + echo "Using Manual Gain" + GAIN_SETTING=" -g $GAIN" +fi + +STATS_SETTING="" + +if [ "$STATS_OUTPUT" = "1" ]; then + echo "Enabling Modem Statistics." + STATS_SETTING=" --stats=100" +fi + +# Start the receive chain. +# Note that we now pass in the SDR centre frequency ($RXFREQ) and 'target' signal frequency ($MFSK1_CENTRE) +# to enable providing additional metadata to Habitat / Sondehub. +rtl_fm -M raw -F9 -s 48000 -p $PPM $GAIN_SETTING$BIAS_SETTING -f $RXFREQ | tee >($DECODER -q --stats=5 -g -m binary --fsk_lower=$MFSK1_LOWER --fsk_upper=$MFSK1_UPPER - - | python3 -m horusdemodlib.uploader --freq_hz $RXFREQ --freq_target_hz $MFSK1_CENTRE ) >($DECODER -q --stats=5 -g -m binary --fsk_lower=$MFSK2_LOWER --fsk_upper=$MFSK2_UPPER - - | python3 -m horusdemodlib.uploader --freq_hz $RXFREQ ) > /dev/null diff --git a/docker_dual_rtty_4fsk.sh b/docker_dual_rtty_4fsk.sh new file mode 100755 index 0000000..85ce823 --- /dev/null +++ b/docker_dual_rtty_4fsk.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash +# +# Dual RTTY / Horus Binary Decoder Script +# Intended for use on Horus flights, with the following payload frequencies: +# RTTY: 434.650 MHz - Callsign 'HORUS' +# MFSK: 434.660 MHz - Callsign 'HORUSBINARY' +# +# The SDR is tuned 5 kHz below the RTTY frequency, and the frequency estimators are set across the two frequencies. +# Modem statistics are sent out via a new 'MODEM_STATS' UDP broadcast message every second. +# + +# Calculate the frequency estimator limits +# Note - these are somewhat hard-coded for this dual-RX application. +RTTY_LOWER=$(echo "$RTTY_SIGNAL - $RXBANDWIDTH/2" | bc) +RTTY_UPPER=$(echo "$RTTY_SIGNAL + $RXBANDWIDTH/2" | bc) +RTTY_CENTRE=$(echo "$RXFREQ + $RTTY_SIGNAL" | bc) + +MFSK_LOWER=$(echo "$MFSK_SIGNAL - $RXBANDWIDTH/2" | bc) +MFSK_UPPER=$(echo "$MFSK_SIGNAL + $RXBANDWIDTH/2" | bc) +MFSK_CENTRE=$(echo "$RXFREQ + $MFSK_SIGNAL" | bc) + +echo "Using SDR Centre Frequency: $RXFREQ Hz." +echo "Using RTTY estimation range: $RTTY_LOWER - $RTTY_UPPER Hz" +echo "Using MFSK estimation range: $MFSK_LOWER - $MFSK_UPPER Hz" + +BIAS_SETTING="" + +if [ "$BIAS" = "1" ]; then + echo "Enabling Bias Tee." + BIAS_SETTING=" -T" +fi + +GAIN_SETTING="" +if [ "$GAIN" = "0" ]; then + echo "Using AGC." + GAIN_SETTING="" +else + echo "Using Manual Gain" + GAIN_SETTING=" -g $GAIN" +fi + +STATS_SETTING="" + +if [ "$STATS_OUTPUT" = "1" ]; then + echo "Enabling Modem Statistics." + STATS_SETTING=" --stats=100" +fi + +# Start the receive chain. +# Note that we now pass in the SDR centre frequency ($RXFREQ) and 'target' signal frequency ($RTTY_CENTRE / $MFSK_CENTRE) +# to enable providing additional metadata to Habitat / Sondehub. +rtl_fm -M raw -F9 -s 48000 -p $PPM $GAIN_SETTING$BIAS_SETTING -f $RXFREQ | tee >($DECODER -q --stats=5 -g -m RTTY --fsk_lower=$RTTY_LOWER --fsk_upper=$RTTY_UPPER - - | python3 -m horusdemodlib.uploader --rtty --freq_hz $RXFREQ --freq_target_hz $RTTY_CENTRE ) >($DECODER -q --stats=5 -g -m binary --fsk_lower=$MFSK_LOWER --fsk_upper=$MFSK_UPPER - - | python3 -m horusdemodlib.uploader --freq_hz $RXFREQ --freq_target_hz $MFSK_CENTRE ) > /dev/null diff --git a/docker_rtlsdr.sh b/docker_single.sh similarity index 60% rename from docker_rtlsdr.sh rename to docker_single.sh index 814bd25..0c08a50 100755 --- a/docker_rtlsdr.sh +++ b/docker_single.sh @@ -5,30 +5,6 @@ # Uses rtl_fm to receive a chunk of spectrum, and passes it into horus_demod. # -# Check that the horus_demod decoder has been compiled. -DECODER=./build/src/horus_demod -if [ -f "$DECODER" ]; then - echo "Found horus_demod." -else - echo "ERROR - $DECODER does not exist - have you compiled it yet?" - exit 1 -fi - -# Check that bc is available on the system path. -if echo "1+1" | bc > /dev/null; then - echo "Found bc." -else - echo "ERROR - Cannot find bc - Did you install it?" - exit 1 -fi - -# Use a local venv if it exists -VENV_DIR=venv -if [ -d "$VENV_DIR" ]; then - echo "Entering venv." - source $VENV_DIR/bin/activate -fi - # Calculate the SDR tuning frequency SDR_RX_FREQ=$(echo "$RXFREQ - $RXBANDWIDTH/2 - 1000" | bc) @@ -58,4 +34,4 @@ fi # Start the receive chain. # Note that we now pass in the SDR centre frequency ($SDR_RX_FREQ) and 'target' signal frequency ($RXFREQ) # to enable providing additional metadata to Habitat / Sondehub. -rtl_fm -M raw -F9 -s 48000 -p $PPM $GAIN_SETTING$BIAS_SETTING -f $SDR_RX_FREQ | $DECODER -q --stats=5 -g -m binary --fsk_lower=$FSK_LOWER --fsk_upper=$FSK_UPPER - - | python -m horusdemodlib.uploader --freq_hz $SDR_RX_FREQ --freq_target_hz $RXFREQ $@ +rtl_fm -M raw -F9 -s 48000 -p $PPM $GAIN_SETTING$BIAS_SETTING -f $SDR_RX_FREQ | $DECODER -q --stats=5 -g -m binary --fsk_lower=$FSK_LOWER --fsk_upper=$FSK_UPPER - - | python3 -m horusdemodlib.uploader --freq_hz $SDR_RX_FREQ --freq_target_hz $RXFREQ $@ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f5a1ebb..7ab8edf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -63,3 +63,5 @@ add_definitions(-DHORUS_L2_RX -DINTERLEAVER -DSCRAMBLER -DRUN_TIME_TABLES) add_executable(horus_demod horus_demod.c horus_api.c horus_l2.c golay23.c fsk.c kiss_fft.c) target_link_libraries(horus_demod m horus ${CMAKE_REQUIRED_LIBRARIES}) +install(TARGETS fsk_mod fsk_demod fsk_get_test_bits fsk_put_test_bits drs232 drs232_ldpc horus_gen_test_bits horus_demod DESTINATION bin) + diff --git a/user.env.example b/user.env.example index 2f0f198..2b5135a 100644 --- a/user.env.example +++ b/user.env.example @@ -1,6 +1,4 @@ -# Receive *centre* frequency, in Hz -# Note: The SDR will be tuned to RXBANDWIDTH/2 below this frequency. -RXFREQ=434200000 +### General SDR settings ### # Receiver Gain. Set this to 0 to use automatic gain control, otherwise if running a # preamplifier, you may want to experiment with different gain settings to optimize @@ -14,13 +12,81 @@ BIAS=0 # Receiver PPM offset PPM=0 -# Frequency estimator bandwidth. The wider the bandwidth, the more drift and frequency error the modem can tolerate, -# but the higher the chance that the modem will lock on to a strong spurious signal. -# Note: The SDR will be tuned to RXFREQ-RXBANDWIDTH/2, and the estimator set to look at 0-RXBANDWIDTH Hz. -RXBANDWIDTH=10000 - # Enable (1) or disable (0) modem statistics output. # If enabled, modem statistics are written to stats.txt, and can be observed # during decoding by running: tail -f stats.txt | python fskstats.py STATS_OUTPUT=0 +# Select decoder to tun +DECODER=horus_demod + + + +########################################################## +### NOTE: Only uncomment one of the settings sections! ### +########################################################## + +### Single 4FSK settings ### + +# Script name +DEMODSCRIPT="docker_single.sh" + +# Receive *centre* frequency, in Hz +# Note: The SDR will be tuned to RXBANDWIDTH/2 below this frequency. +RXFREQ=434200000 + +# Frequency estimator bandwidth. The wider the bandwidth, the more drift and frequency error the modem can tolerate, +# but the higher the chance that the modem will lock on to a strong spurious signal. +# Note: The SDR will be tuned to RXFREQ-RXBANDWIDTH/2, and the estimator set to look at 0-RXBANDWIDTH Hz. +RXBANDWIDTH=10000 + + + +### Dual 4FSK settings ### + +# Script name +#DEMODSCRIPT="docker_dual_4fsk.sh" + +# Receive requency, in Hz. This is the frequency the SDR is tuned to. +#RXFREQ=434195000 + +# Frequency estimator bandwidth. The wider the bandwidth, the more drift and frequency error the modem can tolerate, +# but the higher the chance that the modem will lock on to a strong spurious signal. +#RXBANDWIDTH=5000 + +# Where in the passband we expect to find the Lower Horus Binary (MFSK) signal, in Hz. +# For this example, this is on 434.290 MHz, so with a SDR frequency of 434.195 MHz, +# we expect to find the signal at approx +5 kHz. +# Note that the signal must be located ABOVE the centre frequency of the receiver. +#MFSK1_SIGNAL=5000 + +# Where in the receiver passband we expect to find the higher Horus Binary (MFSK) signal, in Hz. +# In this example, our second frequency is at 434.210 MHz, so with a SDR frequency of 434.195 MHz, +# we expect to find the signal at approx +15 kHz. +#MFSK2_SIGNAL=15000 + + + +## Dual RTTY 4FSK settings ### + +# Script name +#DEMODSCRIPT="docker_dual_rtty_4fsk.sh" + +# Receive requency, in Hz. This is the frequency the SDR is tuned to. +#RXFREQ=434645000 + +# Frequency estimator bandwidth. The wider the bandwidth, the more drift and frequency error the modem can tolerate, +# but the higher the chance that the modem will lock on to a strong spurious signal. +#RXBANDWIDTH=8000 + +# Where in the passband we expect to find the RTTY signal, in Hz. +# For Horus flights, this is on 434.650 MHz, so with a SDR frequency of 434.645 MHz, +# we expect to find the RTTY signal at approx +5 kHz. +# Note that the signal must be located ABOVE the centre frequency of the receiver. +#RTTY_SIGNAL=5000 + +# Where in the receiver passband we expect to find the Horus Binary (MFSK) signal, in Hz. +# For Horus flights, this is on 434.660 MHz, so with a SDR frequency of 434.645 MHz, +# we expect to find the RTTY signal at approx +15 kHz. +#MFSK_SIGNAL=15000 +