Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 59 additions & 15 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,22 @@ project(blah2)
include(CMakePrintHelpers)
include(CTest)

option(BLAH2_KRAKEN_ONLY "Build only the Kraken capture backend" OFF)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror")

find_package(Threads REQUIRED)
find_package(asio REQUIRED)
find_path(RAPIDJSON_INCLUDE_DIRS "rapidjson/allocators.h")
find_package(ryml CONFIG REQUIRED)
find_package(httplib CONFIG REQUIRED)
find_package(Armadillo CONFIG REQUIRED)
find_package(Armadillo REQUIRED)
find_package(Catch2 CONFIG REQUIRED)

set(CMAKE_PREFIX_PATH "/opt/uhd" ${CMAKE_PREFIX_PATH})
find_package(UHD "4.8.0.0" CONFIG REQUIRED)
if(NOT BLAH2_KRAKEN_ONLY)
set(CMAKE_PREFIX_PATH "/opt/uhd" ${CMAKE_PREFIX_PATH})
find_package(UHD "4.8.0.0" CONFIG REQUIRED)
endif()

set(PROJECT_ROOT "${PROJECT_SOURCE_DIR}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_ROOT}/bin")
Expand All @@ -31,24 +35,46 @@ message("Binary path: ${PROJECT_BINARY_DIR}")
message("Binary test path: ${PROJECT_BINARY_TEST_DIR}")

# include from top-level src dir
include_directories(src ${UHD_INCLUDE_DIRS})
include_directories(src)
if(NOT BLAH2_KRAKEN_ONLY)
include_directories(${UHD_INCLUDE_DIRS})
endif()

# TODO: create FindSdrplay.cmake for this
add_library(sdrplay /usr/local/include/sdrplay_api.h)
set_target_properties(sdrplay PROPERTIES LINKER_LANGUAGE C)
target_link_libraries(sdrplay PUBLIC /usr/local/lib/libsdrplay_api.so.3.15)
if(NOT BLAH2_KRAKEN_ONLY)
add_library(sdrplay /usr/local/include/sdrplay_api.h)
set_target_properties(sdrplay PROPERTIES LINKER_LANGUAGE C)
target_link_libraries(sdrplay PUBLIC /usr/local/lib/libsdrplay_api.so.3.15)
endif()

set(BLAH2_CAPTURE_SOURCES
src/capture/kraken/Kraken.cpp
src/capture/kraken/HeimdallFrame.cpp
)
set(BLAH2_CAPTURE_LIBRARIES)
if(NOT BLAH2_KRAKEN_ONLY)
list(APPEND BLAH2_CAPTURE_SOURCES
src/capture/rspduo/RspDuo.cpp
src/capture/usrp/Usrp.cpp
src/capture/hackrf/HackRf.cpp
)
list(APPEND BLAH2_CAPTURE_LIBRARIES
${UHD_LIBRARIES}
sdrplay
hackrf
)
endif()

# TODO: Move to separate src/CMakeLists.txt
add_executable(blah2
src/blah2.cpp
src/capture/Capture.cpp
src/capture/Source.cpp
src/capture/rspduo/RspDuo.cpp
src/capture/usrp/Usrp.cpp
src/capture/hackrf/HackRf.cpp
src/capture/kraken/Kraken.cpp
${BLAH2_CAPTURE_SOURCES}
src/process/ambiguity/Ambiguity.cpp
src/process/clutter/WienerHopf.cpp
src/process/conditioning/ArrayReferenceSynthesizer.cpp
src/process/fusion/Noncoherent.cpp
src/process/detection/CfarDetector1D.cpp
src/process/detection/Centroid.cpp
src/process/detection/Interpolate.cpp
Expand All @@ -69,14 +95,14 @@ target_link_libraries(blah2 PRIVATE
ryml::ryml
httplib::httplib
armadillo
${UHD_LIBRARIES}
fftw3
fftw3_threads
sdrplay
hackrf
rtlsdr
${BLAH2_CAPTURE_LIBRARIES}
)
target_include_directories(blah2 PRIVATE RAPIDJSON_INCLUDE_DIRS "rapidjson/allocators.h")
if(BLAH2_KRAKEN_ONLY)
target_compile_definitions(blah2 PRIVATE BLAH2_KRAKEN_ONLY=1)
endif()

# unit tests
add_executable(testAmbiguity
Expand Down Expand Up @@ -116,6 +142,24 @@ target_link_libraries(testHammingNumber PRIVATE
set_target_properties(testHammingNumber PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_TEST_UNIT_DIR}")

add_executable(testKrakenMultiChannel
test/unit/capture/kraken/TestHeimdallFrame.cpp
test/unit/process/conditioning/TestArrayReferenceSynthesizer.cpp
test/unit/process/fusion/TestNoncoherent.cpp
src/capture/kraken/HeimdallFrame.cpp
src/process/conditioning/ArrayReferenceSynthesizer.cpp
src/process/fusion/Noncoherent.cpp
src/data/IqData.cpp
src/data/Map.cpp
)
target_link_libraries(testKrakenMultiChannel PRIVATE
Catch2::Catch2WithMain
)
set_target_properties(testKrakenMultiChannel PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_TEST_UNIT_DIR}")

# TODO: Unsure if will be using CTest.
add_test(NAME testAmbiguity COMMAND testAmbiguity)
add_test(NAME testTracker COMMAND testTracker)
add_test(NAME testHammingNumber COMMAND testHammingNumber)
add_test(NAME testKrakenMultiChannel COMMAND testKrakenMultiChannel)
7 changes: 4 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ RUN apt-get update && apt-get install -y software-properties-common \
&& apt-get update \
&& DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get install -y \
g++ make cmake git curl zip unzip doxygen graphviz \
libfftw3-dev pkg-config gfortran libhackrf-dev \
libuhd-dev=4.9.0.0-0ubuntu1~jammy3 \
uhd-host=4.9.0.0-0ubuntu1~jammy3 \
libfftw3-dev libarmadillo-dev pkg-config gfortran libhackrf-dev \
libuhd-dev \
uhd-host \
libusb-dev libusb-1.0.0-dev \
&& apt-get autoremove -y \
&& apt-get clean -y \
Expand All @@ -21,6 +21,7 @@ RUN apt-get update && apt-get install -y software-properties-common \
ENV VCPKG_ROOT=/opt/vcpkg
RUN export PATH="/opt/vcpkg:${PATH}" \
&& git clone https://github.com/microsoft/vcpkg /opt/vcpkg \
&& git -C /opt/vcpkg checkout c8696863d371ab7f46e213d8f5ca923c4aef2a00 \
&& if [ "$(uname -m)" = "aarch64" ]; then export VCPKG_FORCE_SYSTEM_BINARIES=1; fi \
&& /opt/vcpkg/bootstrap-vcpkg.sh -disableMetrics \
&& cd /blah2/lib && vcpkg integrate install \
Expand Down
77 changes: 74 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ A real-time radar which can support various SDR platforms. See a live instance a

## Features

- 2 channel processing for a reference and surveillance signal.
- 2 channel processing for a dedicated reference and surveillance signal.
- Multi-channel KrakenSDR processing through KrakenSDR Suite V2 Heimdall output.
- Optional coherent array-reference synthesis and noncoherent surveillance-map fusion.
- Designed to be used with external RF source (for passive radar or active radar).
- Outputs delay-Doppler maps to a web front-end.
- Record raw IQ data by pressing spacebar on the web front-end.
Expand All @@ -18,7 +20,77 @@ A real-time radar which can support various SDR platforms. See a live instance a
- [USRP](https://www.ettus.com/products/) (only tested on the B210).
- 2x [HackRF](https://greatscottgadgets.com/hackrf/) with clock synchronisation and hardware trigger.
- 2x [RTL-SDR](https://www.rtl-sdr.com/) with clock synchronisation.
- [KrakenSDR](https://www.krakenrf.com/) with 2x channels only.
- [KrakenSDR](https://www.krakenrf.com/) with two to eight coherent channels.

### KrakenSDR Suite V2

The Kraken path consumes the standard TCP data stream from
[KrakenSDR Suite V2](https://github.com/krakenrf/krakensdr_suite). It does not
require a patched DAQ. Run `heimdall_v2`, configure frequency and gain in the
Suite, and use `config/config-kraken.yml` as a starting point. BLAH2 accepts
only calibrated antenna frames; calibration/noise and retuning frames are
discarded.

The Kraken-specific fields are:

```yaml
capture:
fs: 2400000
fc: 204640000
device:
type: "Kraken"
heimdall:
host: "127.0.0.1"
port: 8091
channel_count: 5
reference_channel: 0
surveillance_channels: [0, 1, 2, 3, 4]
process:
performance:
surveillance_workers: 0
fft_threads: 1
reference_synthesis:
mode: "array_eigenbeam"
channels: [0, 1, 2, 3, 4]
```

Suite V2 currently streams at 2.4 MS/s, which must match `capture.fs`. The
Suite's packet metadata is used to verify the channel count and center
frequency; `channel_count` determines how many channels BLAH2 consumes, while
frequency and gain remain configured in the Suite. With `mode: dedicated`,
`reference_channel` is excluded from
`surveillance_channels`, preserving conventional reference/surveillance
operation. With `mode: array_eigenbeam`, the channels listed under
`reference_synthesis.channels` estimate
the dominant common arrival and may also produce independent surveillance
maps. Their ambiguity-map magnitudes are RMS-fused into the ordinary BLAH2 map,
so the API and web UI remain compatible.

`surveillance_channels` defaults to every non-reference channel in dedicated
mode and every capture channel in array-reference mode. The optional
`reference_synthesis.channels` list limits which channels contribute to the
synthesized reference; it defaults to every capture channel.

Two through eight Suite V2 channels are accepted at runtime. Independent
surveillance paths can run concurrently; `surveillance_workers: 0` selects a
CPU-aware automatic limit, while `1` uses serial processing on a constrained
host. `fft_threads` controls the FFTW threads used inside each path. This changes
processing latency only, not map fusion or detector math.

The processor logs each reference update in a machine-readable line containing
the channel count, coherent fraction, coherent gain, and per-channel complex
weight magnitude/phase. This is intended for installation verification; a high
reported gain alone is not proof of improved target detection.

The fused detector output keeps BLAH2's existing timestamp, delay, Doppler and
SNR schema. A Kraken installation therefore remains usable as one ordinary
3lips node. Set the receiver and transmitter coordinates under `location` for
the selected illuminator; the array channels are not separate 3lips
nodes.

The existing `docker/Dockerfile-kraken` builds this same BLAH2 processor with
only the Kraken capture backend dependencies. The default `Dockerfile` remains
the multi-backend build for RSPduo, USRP, HackRF and Kraken installations.

## Services

Expand Down Expand Up @@ -70,7 +142,6 @@ The radar processing output is available on [http://localhost:49152](http://loca

- Add a tracker in delay-Doppler space.
- Support for the HackRF/RTL-SDR using a front-end mixer, to sample 2 RF channels in 1 stream.
- Support for the Kraken SDR with all 5 channels.
- Add [SoapySDR](https://github.com/pothosware/SoapySDR) support for the [C++ API](https://github.com/pothosware/SoapySDR/wiki/Cpp_API_Example) to include a wide range of SDR platforms.

## FAQ
Expand Down
39 changes: 30 additions & 9 deletions config/config-kraken.yml
Original file line number Diff line number Diff line change
@@ -1,23 +1,35 @@
capture:
fs: 2000000
# Example values. Keep these in sync with KrakenSDR Suite V2.
# KrakenSDR Suite V2 currently streams at 2.4 MS/s.
fs: 2400000
fc: 204640000
device:
type: "Kraken"
gain: [15.0, 15.0]
array:
x: [0, 0]
y: [0, 0]
z: [0, 0]
boresight: 0.0
# Standard KrakenSDR Suite V2 Heimdall data interface.
heimdall:
host: "127.0.0.1"
port: 8091
# Must match the number of channels streamed by the Suite.
channel_count: 5
reference_channel: 0
# Channels that produce independent surveillance maps. In array-eigenbeam
# mode these may overlap with the reference-synthesis channels below.
surveillance_channels: [0, 1, 2, 3, 4]
replay:
state: false
loop: true
file: '/opt/blah2/replay/file.kraken'

process:
performance:
# 0 chooses a CPU-aware automatic value. Set to 1 to minimize peak CPU,
# or up to the surveillance-channel count on a workstation.
surveillance_workers: 0
# Keep this at 1 when surveillance paths run concurrently.
fft_threads: 1
data:
cpi: 0.5
buffer: 1.5
buffer: 2.0
overlap: 0
ambiguity:
delayMin: -10
Expand All @@ -28,6 +40,15 @@ process:
enable: true
delayMin: -10
delayMax: 400
reference_synthesis:
mode: "array_eigenbeam"
# Optional; all capture channels are used when omitted.
channels: [0, 1, 2, 3, 4]
analysis_samples: 32768
analysis_interval: 10
power_iterations: 12
covariance_smoothing: 0.8
diagonal_loading: 0.001
detection:
enable: true
pfa: 0.00001
Expand Down Expand Up @@ -80,7 +101,7 @@ location:
name: "Mount Lofty"

save:
iq: true
iq: false
map: false
detection: false
timing: false
Expand Down
25 changes: 16 additions & 9 deletions docker/Dockerfile-kraken
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,31 @@ RUN apt-get update && apt-get install -y software-properties-common \
&& apt-get update \
&& DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get install -y \
g++ make cmake git curl zip unzip doxygen graphviz \
libfftw3-dev pkg-config gfortran \
libusb-dev libusb-1.0.0-dev \
libfftw3-dev libarmadillo-dev pkg-config gfortran \
&& apt-get autoremove -y \
&& apt-get clean -y \
&& rm -rf /var/lib/apt/lists/*

# install RTL-SDR API
RUN git clone https://github.com/krakenrf/librtlsdr /opt/librtlsdr \
&& cd /opt/librtlsdr && mkdir build && cd build \
&& cmake ../ -DINSTALL_UDEV_RULES=ON -DDETACH_KERNEL_DRIVER=ON && make && make install && ldconfig
# Install the portable dependencies used by the existing Kraken image without
# pulling in the unrelated SDRplay, UHD, or HackRF development packages.
ENV VCPKG_ROOT=/opt/vcpkg
RUN git clone https://github.com/microsoft/vcpkg /opt/vcpkg \
&& git -C /opt/vcpkg checkout c8696863d371ab7f46e213d8f5ca923c4aef2a00 \
&& /opt/vcpkg/bootstrap-vcpkg.sh -disableMetrics \
&& cd /blah2/lib \
&& cp vcpkg-kraken.json vcpkg.json \
&& /opt/vcpkg/vcpkg install --clean-after-build

FROM blah2_env as blah2
LABEL maintainer="30hours <nathan@30hours.dev>"

ADD src src
ADD test test
ADD CMakeLists.txt CMakePresets.json Doxyfile /blah2/
RUN mkdir -p build && cd build && cmake -S . --preset prod-release \
-DCMAKE_PREFIX_PATH=$(echo /blah2/lib/vcpkg_installed/*/share) .. \
&& cd prod-release && make
RUN cmake -S /blah2 -B /blah2/build \
-DCMAKE_BUILD_TYPE=Release \
-DBLAH2_KRAKEN_ONLY=ON \
-DCMAKE_TOOLCHAIN_FILE=/opt/vcpkg/scripts/buildsystems/vcpkg.cmake \
-DVCPKG_INSTALLED_DIR=/blah2/lib/vcpkg_installed \
&& cmake --build /blah2/build --parallel
RUN chmod +x bin/blah2
19 changes: 19 additions & 0 deletions lib/vcpkg-kraken.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "blah2-kraken",
"version": "1.0.0",
"dependencies": [
{ "name": "catch2", "version>=": "3.4.0" },
{ "name": "rapidjson", "version>=": "1.1.0" },
{ "name": "asio", "version>=": "1.28.0" },
{ "name": "cpp-httplib", "version>=": "0.12.2" },
{ "name": "ryml", "version>=": "0.5.0" }
],
"builtin-baseline": "c8696863d371ab7f46e213d8f5ca923c4aef2a00",
"overrides": [
{ "name": "catch2", "version": "3.4.0" },
{ "name": "rapidjson", "version": "1.1.0" },
{ "name": "asio", "version": "1.28.0" },
{ "name": "cpp-httplib", "version": "0.12.2" },
{ "name": "ryml", "version": "0.5.0" }
]
}
4 changes: 1 addition & 3 deletions lib/vcpkg.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
{ "name": "rapidjson", "version>=": "1.1.0" },
{ "name": "asio", "version>=": "1.28.0" },
{ "name": "cpp-httplib", "version>=": "0.12.2" },
{ "name": "armadillo", "version>=": "12.0.1" },
{ "name": "ryml", "version>=": "0.5.0" }
],
"builtin-baseline": "c8696863d371ab7f46e213d8f5ca923c4aef2a00",
Expand All @@ -15,7 +14,6 @@
{ "name": "rapidjson", "version": "1.1.0" },
{ "name": "asio", "version": "1.28.0" },
{ "name": "cpp-httplib", "version": "0.12.2" },
{ "name": "armadillo", "version": "12.0.1" },
{ "name": "ryml", "version": "0.5.0" }
]
}
}
Loading