mirror of
https://github.com/30hours/blah2.git
synced 2024-11-18 12:33:58 +00:00
Add doxygen comments
This commit is contained in:
parent
d432945c0b
commit
2d325d257d
14 changed files with 2963 additions and 87 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -4,3 +4,7 @@ bin/*
|
||||||
!bin/README.md
|
!bin/README.md
|
||||||
*.a
|
*.a
|
||||||
*.so
|
*.so
|
||||||
|
.vscode/
|
||||||
|
doc/html/*
|
||||||
|
doc/latex/*
|
||||||
|
!doc/html/example.png
|
||||||
|
|
|
@ -4,7 +4,7 @@ MAINTAINER 30hours <nathan@30hours.dev>
|
||||||
WORKDIR blah2
|
WORKDIR blah2
|
||||||
ADD lib lib
|
ADD lib lib
|
||||||
RUN apt-get update
|
RUN apt-get update
|
||||||
RUN apt-get install -y g++ make cmake libfftw3-dev liblapack-dev libopenblas-dev xz-utils libudev-dev libusb-1.0.0-dev sudo systemd
|
RUN apt-get install -y g++ make cmake libfftw3-dev liblapack-dev libopenblas-dev xz-utils libudev-dev libusb-1.0.0-dev sudo systemd doxygen graphviz
|
||||||
RUN cd lib && tar xf armadillo-12.0.1.tar.xz && cd armadillo-12.0.1 && cmake . && make install
|
RUN cd lib && tar xf armadillo-12.0.1.tar.xz && cd armadillo-12.0.1 && cmake . && make install
|
||||||
RUN cd lib/sdrplay-3.0.7 && mkdir -p /etc/udev/rules.d && yes | ./install_lib.sh
|
RUN cd lib/sdrplay-3.0.7 && mkdir -p /etc/udev/rules.d && yes | ./install_lib.sh
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,5 @@
|
||||||
## [0.1] - 04/May/2023
|
## [0.1] - 04/May/2023
|
||||||
- Initial release
|
- Initial release
|
||||||
|
|
||||||
|
## [0.2] - 20/May/2023
|
||||||
|
- Add doxygen comments
|
||||||
|
|
1
doc/html/example.png
Symbolic link
1
doc/html/example.png
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../example.png
|
|
@ -1,20 +1,16 @@
|
||||||
// A real-time radar.
|
/// @file blah2.cpp
|
||||||
|
/// @brief A real-time radar.
|
||||||
// Author: github.com/30hours
|
/// @author 30hours
|
||||||
// Date: 31/Jan/2023
|
|
||||||
// License: MIT
|
|
||||||
|
|
||||||
#define RYML_SINGLE_HDR_DEFINE_NOW
|
#define RYML_SINGLE_HDR_DEFINE_NOW
|
||||||
|
|
||||||
#include <ryml-0.5.0.hpp>
|
#include <ryml-0.5.0.hpp>
|
||||||
#include <asio.hpp>
|
#include <asio.hpp>
|
||||||
|
|
||||||
#include <Capture.h>
|
#include <Capture.h>
|
||||||
#include <Ambiguity.h>
|
#include <Ambiguity.h>
|
||||||
#include <WienerHopf.h>
|
#include <WienerHopf.h>
|
||||||
#include <IqData.h>
|
#include <IqData.h>
|
||||||
#include <Map.h>
|
#include <Map.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
/// @file Capture.h
|
||||||
|
/// @class Capture
|
||||||
|
/// @brief A class for a generic IQ capture device.
|
||||||
|
/// @author 30hours
|
||||||
|
|
||||||
#ifndef CAPTURE_H
|
#ifndef CAPTURE_H
|
||||||
#define CAPTURE_H
|
#define CAPTURE_H
|
||||||
|
|
||||||
|
@ -7,20 +12,53 @@
|
||||||
class Capture
|
class Capture
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
/// @brief The valid capture devices.
|
||||||
static const std::string VALID_TYPE[2];
|
static const std::string VALID_TYPE[2];
|
||||||
bool replay;
|
|
||||||
bool loop;
|
|
||||||
std::string file;
|
|
||||||
public:
|
|
||||||
std::string type;
|
|
||||||
uint32_t fs;
|
|
||||||
uint32_t fc;
|
|
||||||
bool saveIq;
|
|
||||||
std::string path;
|
|
||||||
Capture(std::string type, uint32_t fs, uint32_t fc, std::string path);
|
|
||||||
void process(IqData *buffer1, IqData *buffer2);
|
|
||||||
void set_replay(bool loop, std::string file);
|
|
||||||
|
|
||||||
|
/// @brief True if file replay is enabled.
|
||||||
|
bool replay;
|
||||||
|
|
||||||
|
/// @brief True if replay file should loop when complete.
|
||||||
|
bool loop;
|
||||||
|
|
||||||
|
/// @brief Absolute path of file to replay.
|
||||||
|
std::string file;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// @brief The capture device type.
|
||||||
|
std::string type;
|
||||||
|
|
||||||
|
/// @brief Sampling frequency (Hz).
|
||||||
|
uint32_t fs;
|
||||||
|
|
||||||
|
/// @brief Center frequency (Hz).
|
||||||
|
uint32_t fc;
|
||||||
|
|
||||||
|
/// @brief True if IQ data is saved to file.
|
||||||
|
bool saveIq;
|
||||||
|
|
||||||
|
/// @brief Absolute path to IQ save location.
|
||||||
|
std::string path;
|
||||||
|
|
||||||
|
/// @brief Constructor.
|
||||||
|
/// @param type The capture device type.
|
||||||
|
/// @param fs Sampling frequency (Hz).
|
||||||
|
/// @param fc Center frequency (Hz).
|
||||||
|
/// @param path Absolute path to IQ save location.
|
||||||
|
/// @return The object.
|
||||||
|
Capture(std::string type, uint32_t fs, uint32_t fc, std::string path);
|
||||||
|
|
||||||
|
/// @brief Implement the capture process.
|
||||||
|
/// @param buffer1 Buffer for reference samples.
|
||||||
|
/// @param buffer2 Buffer for surveillance samples.
|
||||||
|
/// @return Void.
|
||||||
|
void process(IqData *buffer1, IqData *buffer2);
|
||||||
|
|
||||||
|
/// @brief Set parameters to enable file replay.
|
||||||
|
/// @param loop True if replay file should loop when complete.
|
||||||
|
/// @param file Absolute path of file to replay.
|
||||||
|
/// @return Void.
|
||||||
|
void set_replay(bool loop, std::string file);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -1,30 +1,3 @@
|
||||||
/******************************************************************************
|
|
||||||
*
|
|
||||||
* Filename: rspduo_iq_recorder.c
|
|
||||||
*
|
|
||||||
* Author: Michael Parker
|
|
||||||
*
|
|
||||||
* Created: 13 Feb 2022
|
|
||||||
*
|
|
||||||
* Description: IQ Recorder for SDRplay RSPduo
|
|
||||||
*
|
|
||||||
* Loosely based upon the sdrplay_api_sample_app.c and sdr_play.c examples
|
|
||||||
* provided in the SDRplay API V3 documentation
|
|
||||||
* This should be read in conjuction with that documentation
|
|
||||||
*
|
|
||||||
* For coherent operation the use of sdrplay_api_Tuner_Both is most important
|
|
||||||
* This clue was provided by Gustaw Mazurek of WUT
|
|
||||||
*
|
|
||||||
* Revision History:
|
|
||||||
*
|
|
||||||
* 13 Feb 2022 MCP Initial coding
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* https://github.com/fventuri/gr-sdrplay/issues/2
|
|
||||||
* https://github.com/g4eev/RSPduoEME/blob/main/rspduointerface.cpp
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#include <RspDuo.h>
|
#include <RspDuo.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
|
@ -1,3 +1,21 @@
|
||||||
|
/// @file RspDuo.h
|
||||||
|
/// @class RspDuo
|
||||||
|
/// @brief A class to capture data on the SDRplay RspDuo.
|
||||||
|
/// @details Loosely based upon the sdrplay_api_sample_app.c and sdr_play.c examples
|
||||||
|
/// provided in the SDRplay API V3 documentation.
|
||||||
|
/// This should be read in conjuction with that documentation
|
||||||
|
///
|
||||||
|
/// For coherent operation the use of sdrplay_api_Tuner_Both is most important
|
||||||
|
/// This clue was provided by Gustaw Mazurek of WUT
|
||||||
|
/// <https://github.com/fventuri/gr-sdrplay/issues/2>
|
||||||
|
/// <https://github.com/g4eev/RSPduoEME/blob/main/rspduointerface.cpp>
|
||||||
|
///
|
||||||
|
/// Reference for using C style callback API with a C++ wrapper:
|
||||||
|
/// <https://stackoverflow.com/questions/63768893/pointer-problem-using-functions-from-non-object-api-in-objects?rq=1>
|
||||||
|
/// @author 30hours
|
||||||
|
/// @author Michael P
|
||||||
|
/// @todo Remove max time.
|
||||||
|
|
||||||
#ifndef RSPDUO_H
|
#ifndef RSPDUO_H
|
||||||
#define RSPDUO_H
|
#define RSPDUO_H
|
||||||
|
|
||||||
|
@ -6,76 +24,212 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <IqData.h>
|
#include <IqData.h>
|
||||||
|
|
||||||
#define BUFFER_SIZE_NR 1024 /* standard size of buffers */
|
#define BUFFER_SIZE_NR 1024
|
||||||
|
|
||||||
// https://stackoverflow.com/questions/63768893/pointer-problem-using-functions-from-non-object-api-in-objects?rq=1
|
|
||||||
|
|
||||||
class RspDuo
|
class RspDuo
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
uint32_t fc; // frequency (Hz)
|
/// @brief Center frequency (Hz)
|
||||||
int chunk_time_nr; // chunk time of recording (s)
|
uint32_t fc;
|
||||||
int agc_bandwidth_nr; // agc bandwidth (Hz)
|
/// @brief chunk time of recording (s)
|
||||||
int agc_set_point_nr; // agc set point (dBfs)
|
int chunk_time_nr;
|
||||||
int gain_reduction_nr; // gain reduction (dB)
|
/// @brief AGC bandwidth (Hz)
|
||||||
int lna_state_nr; // lna state
|
int agc_bandwidth_nr;
|
||||||
int nDecimation; // decimation factor
|
/// @brief AGC set point (dBfs)
|
||||||
bool rf_notch_fg; // MW and FM notch filters
|
int agc_set_point_nr;
|
||||||
bool dab_notch_fg; // DAB notch filter
|
/// @brief Gain reduction (dB).
|
||||||
bool usb_bulk_fg; // usb bulk transfer mode
|
int gain_reduction_nr;
|
||||||
bool small_verbose_fg; // debugging
|
/// @brief LNA state
|
||||||
bool more_verbose_fg; // debugging
|
int lna_state_nr;
|
||||||
std::string path; // file path
|
/// @brief Decimation factor (integer).
|
||||||
bool capture; // flag to capture
|
int nDecimation;
|
||||||
static const double MAX_FREQUENCY_NR;
|
/// @brief MW and FM notch filters.
|
||||||
static const uint8_t DEF_DECIMATION_NR;
|
bool rf_notch_fg;
|
||||||
static const int DEF_WAIT_TIME_NR; // default wait time before recording
|
/// @brief DAB notch filter.
|
||||||
static const int DEF_CHUNK_TIME_NR; // default chunk time of recording
|
bool dab_notch_fg;
|
||||||
static const int MAX_RUN_TIME_NR; // max run time of recording
|
/// @brief USB bulk transfer mode.
|
||||||
static const int DEF_AGC_BANDWIDTH_NR; // default agc bandwidth
|
bool usb_bulk_fg;
|
||||||
static const int MIN_AGC_SET_POINT_NR; // min agc set point
|
/// @brief Debugging.
|
||||||
static const int DEF_AGC_SET_POINT_NR; // default agc set point
|
bool small_verbose_fg;
|
||||||
static const int MIN_GAIN_REDUCTION_NR; // min gain reduction
|
/// @brief Debugging.
|
||||||
static const int DEF_GAIN_REDUCTION_NR; // default gain reduction
|
bool more_verbose_fg;
|
||||||
static const int MAX_GAIN_REDUCTION_NR; // max gain reduction
|
/// @brief File path.
|
||||||
static const int DEF_LNA_STATE_NR; // default lna state
|
std::string path;
|
||||||
static const int MAX_LNA_STATE_NR; // max lna state
|
/// @brief True if capture is enabled.
|
||||||
static const int DEF_SAMPLE_FREQUENCY_NR; // default sample frequency
|
bool capture;
|
||||||
static const int DEF_SAMPLE_RATE_NR; // default sample rate
|
|
||||||
|
|
||||||
|
/// @brief Maximum frequency (Hz).
|
||||||
|
static const double MAX_FREQUENCY_NR;
|
||||||
|
/// @brief Default decimation.
|
||||||
|
static const uint8_t DEF_DECIMATION_NR;
|
||||||
|
/// @brief Default wait time before recording.
|
||||||
|
static const int DEF_WAIT_TIME_NR;
|
||||||
|
/// @brief Default chunk time of recording.
|
||||||
|
static const int DEF_CHUNK_TIME_NR;
|
||||||
|
/// @brief Maximum run time of recording.
|
||||||
|
static const int MAX_RUN_TIME_NR;
|
||||||
|
/// @brief Default AGC bandwidth.
|
||||||
|
static const int DEF_AGC_BANDWIDTH_NR;
|
||||||
|
/// @brief Minimum AGC set point.
|
||||||
|
static const int MIN_AGC_SET_POINT_NR;
|
||||||
|
/// @brief Default AGC set point.
|
||||||
|
static const int DEF_AGC_SET_POINT_NR;
|
||||||
|
/// @brief Minimum gain reduction.
|
||||||
|
static const int MIN_GAIN_REDUCTION_NR;
|
||||||
|
/// @brief Default gain reduction.
|
||||||
|
static const int DEF_GAIN_REDUCTION_NR;
|
||||||
|
/// @brief Maximum gain reduction.
|
||||||
|
static const int MAX_GAIN_REDUCTION_NR;
|
||||||
|
/// @brief Default LNA state.
|
||||||
|
static const int DEF_LNA_STATE_NR;
|
||||||
|
/// @brief Max LNA state.
|
||||||
|
static const int MAX_LNA_STATE_NR;
|
||||||
|
/// @brief Default sample frequency.
|
||||||
|
static const int DEF_SAMPLE_FREQUENCY_NR;
|
||||||
|
/// @brief Default sample rate.
|
||||||
|
static const int DEF_SAMPLE_RATE_NR;
|
||||||
|
|
||||||
|
/// @brief Check parameters for valid for capture device.
|
||||||
|
/// @return The object.
|
||||||
void validate();
|
void validate();
|
||||||
|
|
||||||
|
/// @brief Start API functions.
|
||||||
|
/// @return The object.
|
||||||
void open_api();
|
void open_api();
|
||||||
|
|
||||||
|
/// @brief Device selection function.
|
||||||
|
/// @return The object.
|
||||||
void get_device();
|
void get_device();
|
||||||
|
|
||||||
|
/// @brief Set device parameters.
|
||||||
|
/// @return The object.
|
||||||
void set_device_parameters();
|
void set_device_parameters();
|
||||||
|
|
||||||
|
/// @brief Wrapper for C style callback function for stream_a_callback().
|
||||||
|
/// @param xi Pointer to real part of sample.
|
||||||
|
/// @param xq Pointer to imag part of sample.
|
||||||
|
/// @param params As defined in SDRplay API.
|
||||||
|
/// @param numSamples Number of samples in block.
|
||||||
|
/// @param reset As defined in SDRplay API.
|
||||||
|
/// @param cbContext As defined in SDRplay API.
|
||||||
|
/// @return Void.
|
||||||
static void _stream_a_callback(short *xi, short *xq, sdrplay_api_StreamCbParamsT *params, unsigned int numSamples, unsigned int reset, void *cbContext)
|
static void _stream_a_callback(short *xi, short *xq, sdrplay_api_StreamCbParamsT *params, unsigned int numSamples, unsigned int reset, void *cbContext)
|
||||||
{
|
{
|
||||||
static_cast<RspDuo *>(cbContext)->stream_a_callback(xi, xq, params, numSamples, reset, cbContext);
|
static_cast<RspDuo *>(cbContext)->stream_a_callback(xi, xq, params, numSamples, reset, cbContext);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// @brief Wrapper for C style callback function for stream_b_callback().
|
||||||
|
/// @param xi Pointer to real part of sample.
|
||||||
|
/// @param xq Pointer to imag part of sample.
|
||||||
|
/// @param params As defined in SDRplay API.
|
||||||
|
/// @param numSamples Number of samples in block.
|
||||||
|
/// @param reset As defined in SDRplay API.
|
||||||
|
/// @param cbContext As defined in SDRplay API.
|
||||||
|
/// @return Void.
|
||||||
static void _stream_b_callback(short *xi, short *xq, sdrplay_api_StreamCbParamsT *params, unsigned int numSamples, unsigned int reset, void *cbContext)
|
static void _stream_b_callback(short *xi, short *xq, sdrplay_api_StreamCbParamsT *params, unsigned int numSamples, unsigned int reset, void *cbContext)
|
||||||
{
|
{
|
||||||
static_cast<RspDuo *>(cbContext)->stream_b_callback(xi, xq, params, numSamples, reset, cbContext);
|
static_cast<RspDuo *>(cbContext)->stream_b_callback(xi, xq, params, numSamples, reset, cbContext);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// @brief Wrapper for C style callback function for event_callback().
|
||||||
|
/// @param eventId As defined in SDRplay API.
|
||||||
|
/// @param tuner As defined in SDRplay API.
|
||||||
|
/// @param params As defined in SDRplay API.
|
||||||
|
/// @param cbContext As defined in SDRplay API.
|
||||||
|
/// @return Void.
|
||||||
static void _event_callback(sdrplay_api_EventT eventId, sdrplay_api_TunerSelectT tuner, sdrplay_api_EventParamsT *params, void *cbContext)
|
static void _event_callback(sdrplay_api_EventT eventId, sdrplay_api_TunerSelectT tuner, sdrplay_api_EventParamsT *params, void *cbContext)
|
||||||
{
|
{
|
||||||
static_cast<RspDuo *>(cbContext)->event_callback(eventId, tuner, params, cbContext);
|
static_cast<RspDuo *>(cbContext)->event_callback(eventId, tuner, params, cbContext);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// @brief Tuner a callback as defined in SDRplay API.
|
||||||
|
/// @param xi Pointer to real part of sample.
|
||||||
|
/// @param xq Pointer to imag part of sample.
|
||||||
|
/// @param params As defined in SDRplay API.
|
||||||
|
/// @param numSamples Number of samples in block.
|
||||||
|
/// @param reset As defined in SDRplay API.
|
||||||
|
/// @param cbContext As defined in SDRplay API.
|
||||||
|
/// @return Void.
|
||||||
void stream_a_callback(short *xi, short *xq, sdrplay_api_StreamCbParamsT *params, unsigned int numSamples, unsigned int reset, void *cbContext);
|
void stream_a_callback(short *xi, short *xq, sdrplay_api_StreamCbParamsT *params, unsigned int numSamples, unsigned int reset, void *cbContext);
|
||||||
|
|
||||||
|
/// @brief Tuner b callback as defined in SDRplay API.
|
||||||
|
/// @param xi Pointer to real part of sample.
|
||||||
|
/// @param xq Pointer to imag part of sample.
|
||||||
|
/// @param params As defined in SDRplay API.
|
||||||
|
/// @param numSamples Number of samples in block.
|
||||||
|
/// @param reset As defined in SDRplay API.
|
||||||
|
/// @param cbContext As defined in SDRplay API.
|
||||||
|
/// @return Void.
|
||||||
void stream_b_callback(short *xi, short *xq, sdrplay_api_StreamCbParamsT *params, unsigned int numSamples, unsigned int reset, void *cbContext);
|
void stream_b_callback(short *xi, short *xq, sdrplay_api_StreamCbParamsT *params, unsigned int numSamples, unsigned int reset, void *cbContext);
|
||||||
|
|
||||||
|
/// @brief Event callback function as defined in SDRplay API.
|
||||||
|
/// @param eventId As defined in SDRplay API.
|
||||||
|
/// @param tuner As defined in SDRplay API.
|
||||||
|
/// @param params As defined in SDRplay API.
|
||||||
|
/// @param cbContext As defined in SDRplay API.
|
||||||
|
/// @return Void.
|
||||||
void event_callback(sdrplay_api_EventT eventId, sdrplay_api_TunerSelectT tuner, sdrplay_api_EventParamsT *params, void *cbContext);
|
void event_callback(sdrplay_api_EventT eventId, sdrplay_api_TunerSelectT tuner, sdrplay_api_EventParamsT *params, void *cbContext);
|
||||||
|
|
||||||
|
/// @brief Start running capture callback function.
|
||||||
|
/// @return Void.
|
||||||
void initialise_device();
|
void initialise_device();
|
||||||
|
|
||||||
|
/// @brief Stop running capture callback function.
|
||||||
|
/// @return Void.
|
||||||
void uninitialise_device();
|
void uninitialise_device();
|
||||||
|
|
||||||
|
/// @brief Internal method to gracefully stop capture..
|
||||||
|
/// @return Void.
|
||||||
void finish();
|
void finish();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/// @brief Constructor.
|
||||||
|
/// @param fc Center frequency (Hz).
|
||||||
|
/// @param path Path to save IQ data.
|
||||||
|
/// @return The object.
|
||||||
RspDuo(uint32_t fc, std::string path);
|
RspDuo(uint32_t fc, std::string path);
|
||||||
|
|
||||||
|
/// @brief Get file name from path.
|
||||||
|
/// @return String of file name based on current time.
|
||||||
std::string set_file(std::string path);
|
std::string set_file(std::string path);
|
||||||
|
|
||||||
|
/// @brief Call methods to start capture.
|
||||||
|
/// @return Void.
|
||||||
void start();
|
void start();
|
||||||
|
|
||||||
|
/// @brief Call methods to gracefully stop capture.
|
||||||
|
/// @return Void.
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
|
/// @brief Implement capture function on RSPduo.
|
||||||
|
/// @param buffer1 Pointer to reference buffer.
|
||||||
|
/// @param buffer2 Pointer to surveillance buffer.
|
||||||
|
/// @return Void.
|
||||||
void process(IqData *buffer1, IqData *buffer2);
|
void process(IqData *buffer1, IqData *buffer2);
|
||||||
|
|
||||||
|
/// @brief Implement replay function on RSPduo.
|
||||||
|
/// @param buffer1 Pointer to reference buffer.
|
||||||
|
/// @param buffer2 Pointer to surveillance buffer.
|
||||||
|
/// @param file Path to file to replay data from.
|
||||||
|
/// @param loop True if samples should loop at EOF.
|
||||||
|
/// @return Void.
|
||||||
void replay(IqData *buffer1, IqData *buffer2, std::string file, bool loop);
|
void replay(IqData *buffer1, IqData *buffer2, std::string file, bool loop);
|
||||||
|
|
||||||
|
/// @brief Open a new file to record IQ.
|
||||||
|
/// @return Void.
|
||||||
void open_file();
|
void open_file();
|
||||||
|
|
||||||
|
/// @brief Close IQ file gracefully.
|
||||||
|
/// @return Void.
|
||||||
void close_file();
|
void close_file();
|
||||||
|
|
||||||
|
/// @brief Setter for capture.
|
||||||
|
/// @param capture True if capture is enabled.
|
||||||
|
/// @return Void.
|
||||||
void set_capture(bool capture);
|
void set_capture(bool capture);
|
||||||
|
|
||||||
|
/// @brief Getter for capture.
|
||||||
|
/// @return True if capture is true.
|
||||||
bool get_capture();
|
bool get_capture();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
/// @file IqData.h
|
||||||
|
/// @class IqData
|
||||||
|
/// @brief A class to store IQ data.
|
||||||
|
/// @details Implements a FIFO queue to store IQ samples.
|
||||||
|
/// @author 30hours
|
||||||
|
|
||||||
#ifndef IQDATA_H
|
#ifndef IQDATA_H
|
||||||
#define IQDATA_H
|
#define IQDATA_H
|
||||||
|
|
||||||
|
@ -8,20 +14,57 @@
|
||||||
class IqData
|
class IqData
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
/// @brief Maximum number of samples.
|
||||||
uint32_t n;
|
uint32_t n;
|
||||||
|
|
||||||
|
/// @brief True if should not push to buffer (mutex).
|
||||||
bool doNotPush;
|
bool doNotPush;
|
||||||
|
|
||||||
|
/// @brief Pointer to IQ data.
|
||||||
std::deque<std::complex<double>> *data;
|
std::deque<std::complex<double>> *data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/// @brief Constructor.
|
||||||
|
/// @param n Number of samples.
|
||||||
|
/// @return The object.
|
||||||
IqData(uint32_t n);
|
IqData(uint32_t n);
|
||||||
|
|
||||||
|
/// @brief Getter for maximum number of samples.
|
||||||
|
/// @return Maximum number of samples.
|
||||||
uint32_t get_n();
|
uint32_t get_n();
|
||||||
|
|
||||||
|
/// @brief Getter for current data length.
|
||||||
|
/// @return Number of samples currently in data.
|
||||||
uint32_t get_length();
|
uint32_t get_length();
|
||||||
|
|
||||||
|
/// @brief Setter for mutex.
|
||||||
|
/// @param doNotPush True if should not push to buffer (mutex).
|
||||||
|
/// @return Void.
|
||||||
void set_doNotPush(bool doNotPush);
|
void set_doNotPush(bool doNotPush);
|
||||||
|
|
||||||
|
/// @brief Getter for mutex.
|
||||||
|
/// @return True if should not push to buffer (mutex).
|
||||||
bool get_doNotPush();
|
bool get_doNotPush();
|
||||||
|
|
||||||
|
/// @brief Getter for data.
|
||||||
|
/// @return IQ data.
|
||||||
std::deque<std::complex<double>> get_data();
|
std::deque<std::complex<double>> get_data();
|
||||||
|
|
||||||
|
/// @brief Push a sample to the queue.
|
||||||
|
/// @param sample A single sample.
|
||||||
|
/// @return Void.
|
||||||
void push_back(std::complex<double> sample);
|
void push_back(std::complex<double> sample);
|
||||||
|
|
||||||
|
/// @brief Pop the front of the queue.
|
||||||
|
/// @return Sample from the front of the queue.
|
||||||
std::complex<double> pop_front();
|
std::complex<double> pop_front();
|
||||||
|
|
||||||
|
/// @brief Print to stdout (debug).
|
||||||
|
/// @return Void.
|
||||||
void print();
|
void print();
|
||||||
|
|
||||||
|
/// @brief Clear samples from the queue.
|
||||||
|
/// @return Void.
|
||||||
void clear();
|
void clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,6 @@
|
||||||
#include "rapidjson/stringbuffer.h"
|
#include "rapidjson/stringbuffer.h"
|
||||||
#include "rapidjson/filewritestream.h"
|
#include "rapidjson/filewritestream.h"
|
||||||
|
|
||||||
// References:
|
|
||||||
// - https://stackoverflow.com/questions/39110263/append-to-an-existing-array-of-json-objects-on-file-using-rapidjson
|
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
template <class T>
|
template <class T>
|
||||||
Map<T>::Map(uint32_t _nRows, uint32_t _nCols)
|
Map<T>::Map(uint32_t _nRows, uint32_t _nCols)
|
||||||
|
|
|
@ -1,3 +1,12 @@
|
||||||
|
/// @file Map.h
|
||||||
|
/// @class Map
|
||||||
|
/// @brief A class to store an ambiguity map.
|
||||||
|
/// @details References:
|
||||||
|
/// <a href="https://stackoverflow.com/questions/39110263/append-to-an-existing-array-of-json-objects-on-file-using-rapidjson">
|
||||||
|
/// Append to an existing array using rapidjson.</a>
|
||||||
|
/// @author 30hours
|
||||||
|
/// @todo Fix memory leak in get_map_db().
|
||||||
|
|
||||||
#ifndef MAP_H
|
#ifndef MAP_H
|
||||||
#define MAP_H
|
#define MAP_H
|
||||||
|
|
||||||
|
@ -11,26 +20,84 @@ template <typename T>
|
||||||
class Map
|
class Map
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
/// @brief Number of rows.
|
||||||
uint32_t nRows;
|
uint32_t nRows;
|
||||||
|
|
||||||
|
/// @brief Number of columns.
|
||||||
uint32_t nCols;
|
uint32_t nCols;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/// @brief Map data to store.
|
||||||
std::vector<std::vector<T>> data;
|
std::vector<std::vector<T>> data;
|
||||||
|
|
||||||
|
/// @brief Delay units of map data (bins).
|
||||||
std::deque<int> delay;
|
std::deque<int> delay;
|
||||||
|
|
||||||
|
/// @brief Doppler units of map data (Hz).
|
||||||
std::deque<double> doppler;
|
std::deque<double> doppler;
|
||||||
|
|
||||||
|
/// @brief Noise power of map (dB).
|
||||||
double noisePower;
|
double noisePower;
|
||||||
|
|
||||||
|
/// @brief Dynamic range of map (dB).
|
||||||
double maxPower;
|
double maxPower;
|
||||||
|
|
||||||
|
/// @brief Constructor.
|
||||||
|
/// @param nRows Number of rows.
|
||||||
|
/// @param nCols Number of columns.
|
||||||
|
/// @return The object.
|
||||||
Map(uint32_t nRows, uint32_t nCols);
|
Map(uint32_t nRows, uint32_t nCols);
|
||||||
|
|
||||||
|
/// @brief Update a row in the 2D map.
|
||||||
|
/// @param i Index of row to update.
|
||||||
|
/// @param row Data to update.
|
||||||
|
/// @return Void.
|
||||||
void set_row(uint32_t i, std::vector<T> row);
|
void set_row(uint32_t i, std::vector<T> row);
|
||||||
|
|
||||||
|
/// @brief Update a column in the 2D map.
|
||||||
|
/// @param i Index of column to update.
|
||||||
|
/// @param col Data to update.
|
||||||
|
/// @return Void.
|
||||||
void set_col(uint32_t i, std::vector<T> col);
|
void set_col(uint32_t i, std::vector<T> col);
|
||||||
|
|
||||||
|
/// @brief Create map metrics (noise power, dynamic range).
|
||||||
|
/// @return Void.
|
||||||
void set_metrics();
|
void set_metrics();
|
||||||
|
|
||||||
|
/// @brief Get the number of rows in the map.
|
||||||
|
/// @return Number of rows.
|
||||||
uint32_t get_nRows();
|
uint32_t get_nRows();
|
||||||
|
|
||||||
|
/// @brief Get the number of columns in the map.
|
||||||
|
/// @return Number of columns.
|
||||||
uint32_t get_nCols();
|
uint32_t get_nCols();
|
||||||
|
|
||||||
|
/// @brief Get a row from the 2D map.
|
||||||
|
/// @param row Index of row to get.
|
||||||
|
/// @return Vector of data.
|
||||||
std::vector<T> get_row(uint32_t row);
|
std::vector<T> get_row(uint32_t row);
|
||||||
|
|
||||||
|
/// @brief Get a column from the 2D map.
|
||||||
|
/// @param col Index of column to get.
|
||||||
|
/// @return Vector of data.
|
||||||
std::vector<T> get_col(uint32_t col);
|
std::vector<T> get_col(uint32_t col);
|
||||||
|
|
||||||
|
/// @brief Get a copy of the map in dB units.
|
||||||
|
/// @return Pointer to dB map.
|
||||||
Map<double> *get_map_db();
|
Map<double> *get_map_db();
|
||||||
|
|
||||||
|
/// @brief Print the map to stdout (for debugging).
|
||||||
|
/// @return Void.
|
||||||
void print();
|
void print();
|
||||||
|
|
||||||
|
/// @brief Generate JSON of the map and metadata.
|
||||||
|
/// @return JSON string.
|
||||||
std::string to_json();
|
std::string to_json();
|
||||||
|
|
||||||
|
/// @brief Append the map to a save file.
|
||||||
|
/// @param json JSON string of map and metadata.
|
||||||
|
/// @param path Path of file to save.
|
||||||
|
/// @return True is save is successful.
|
||||||
bool save(std::string json, std::string path);
|
bool save(std::string json, std::string path);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
/// @file Ambiguity.h
|
||||||
|
/// @class Ambiguity
|
||||||
|
/// @brief A class to implement a ambiguity map processing.
|
||||||
|
/// @details Implements a the batches algorithm as described in Principles of Modern Radar, Volume II, Chapter 17.
|
||||||
|
/// See Fundamentals of Radar Signal Processing (Richards) for more on the pulse-Doppler processing method.
|
||||||
|
/// @author 30hours
|
||||||
|
/// @todo Ambiguity maps are still offset by 1 bin.
|
||||||
|
|
||||||
#ifndef AMBIGUITY_H
|
#ifndef AMBIGUITY_H
|
||||||
#define AMBIGUITY_H
|
#define AMBIGUITY_H
|
||||||
|
|
||||||
|
@ -9,30 +17,79 @@
|
||||||
class Ambiguity
|
class Ambiguity
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
/// @brief Minimum delay (bins).
|
||||||
int32_t delayMin;
|
int32_t delayMin;
|
||||||
|
|
||||||
|
/// @brief Maximum delay (bins).
|
||||||
int32_t delayMax;
|
int32_t delayMax;
|
||||||
|
|
||||||
|
/// @brief Minimum Doppler (Hz).
|
||||||
int32_t dopplerMin;
|
int32_t dopplerMin;
|
||||||
|
|
||||||
|
/// @brief Maximum Doppler (Hz).
|
||||||
int32_t dopplerMax;
|
int32_t dopplerMax;
|
||||||
|
|
||||||
|
/// @brief Sampling frequency (Hz).
|
||||||
uint32_t fs;
|
uint32_t fs;
|
||||||
|
|
||||||
|
/// @brief Number of samples.
|
||||||
uint32_t n;
|
uint32_t n;
|
||||||
|
|
||||||
|
/// @brief Center of Doppler bins (Hz).
|
||||||
double dopplerMiddle;
|
double dopplerMiddle;
|
||||||
|
|
||||||
|
/// @brief Number of delay bins.
|
||||||
uint16_t nDelayBins;
|
uint16_t nDelayBins;
|
||||||
|
|
||||||
|
/// @brief Number of Doppler bins.
|
||||||
uint16_t nDopplerBins;
|
uint16_t nDopplerBins;
|
||||||
|
|
||||||
|
/// @brief Number of correlation samples per pulse.
|
||||||
uint16_t nCorr;
|
uint16_t nCorr;
|
||||||
|
|
||||||
|
/// @brief True CPI time (s).
|
||||||
double cpi;
|
double cpi;
|
||||||
|
|
||||||
|
/// @brief FFTW plans for ambiguity processing.
|
||||||
|
/// @{
|
||||||
fftw_plan fftXi, fftYi, fftZi, fftDoppler;
|
fftw_plan fftXi, fftYi, fftZi, fftDoppler;
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// @brief FFTW storage for ambiguity processing.
|
||||||
|
/// @{
|
||||||
std::complex<double> *dataXi, *dataYi, *dataZi, *dataCorr, *dataDoppler;
|
std::complex<double> *dataXi, *dataYi, *dataZi, *dataCorr, *dataDoppler;
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// @brief Number of samples to perform FFT per pulse.
|
||||||
uint32_t nfft;
|
uint32_t nfft;
|
||||||
|
|
||||||
|
/// @brief Vector storage for ambiguity processing
|
||||||
|
/// @{
|
||||||
std::vector<std::complex<double>> corr, delayProfile;
|
std::vector<std::complex<double>> corr, delayProfile;
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// @brief Pointer to map to store result.
|
||||||
Map<std::complex<double>> *map;
|
Map<std::complex<double>> *map;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/// @brief Constructor.
|
||||||
|
/// @param delayMin Minimum delay (bins).
|
||||||
|
/// @param delayMax Maximum delay (bins).
|
||||||
|
/// @param dopplerMin Minimum Doppler (Hz).
|
||||||
|
/// @param dopplerMax Maximum Doppler (Hz).
|
||||||
|
/// @param fs Sampling frequency (Hz).
|
||||||
|
/// @param n Number of samples.
|
||||||
|
/// @return The object.
|
||||||
Ambiguity(int32_t delayMin, int32_t delayMax, int32_t dopplerMin, int32_t dopplerMax, uint32_t fs, uint32_t n);
|
Ambiguity(int32_t delayMin, int32_t delayMax, int32_t dopplerMin, int32_t dopplerMax, uint32_t fs, uint32_t n);
|
||||||
|
|
||||||
|
/// @brief Destructor.
|
||||||
|
/// @return Void.
|
||||||
~Ambiguity();
|
~Ambiguity();
|
||||||
|
|
||||||
|
/// @brief Implement the ambiguity processor.
|
||||||
|
/// @param x Reference samples.
|
||||||
|
/// @param y Surveillance samples.
|
||||||
|
/// @return Ambiguity map data of IQ samples.
|
||||||
Map<std::complex<double>> *process(IqData *x, IqData *y);
|
Map<std::complex<double>> *process(IqData *x, IqData *y);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
/// @file WienerHopf.h
|
||||||
|
/// @class WienerHopf
|
||||||
|
/// @brief A class to implement a Wiener-Hopf clutter filter.
|
||||||
|
/// @details Implements a <a href="https://en.wikipedia.org/wiki/Wiener_filter#Finite_impulse_response_Wiener_filter_for_discrete_series">Wiener-Hopf filter</a>.
|
||||||
|
/// Uses <a href="https://en.wikipedia.org/wiki/Cholesky_decomposition">Cholesky decomposition</a> to speed up matrix inversion, as the Toeplitz matrix is positive-definite and Hermitian.
|
||||||
|
/// @author 30hours
|
||||||
|
/// @todo Fix the segmentation fault from clutter filter numerical instability.
|
||||||
|
|
||||||
#ifndef WIENERHOPF_H
|
#ifndef WIENERHOPF_H
|
||||||
#define WIENERHOPF_H
|
#define WIENERHOPF_H
|
||||||
|
|
||||||
|
@ -9,23 +17,64 @@
|
||||||
class WienerHopf
|
class WienerHopf
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
/// @brief Minimum clutter filter delay (bins).
|
||||||
int32_t delayMin;
|
int32_t delayMin;
|
||||||
|
|
||||||
|
/// @brief Maximum clutter filter delay (bins).
|
||||||
int32_t delayMax;
|
int32_t delayMax;
|
||||||
|
|
||||||
|
/// @brief Number of bins (delayMax - delayMin + 1).
|
||||||
uint32_t nBins;
|
uint32_t nBins;
|
||||||
|
|
||||||
|
/// @brief Number of samples per CPI.
|
||||||
uint32_t nSamples;
|
uint32_t nSamples;
|
||||||
|
|
||||||
|
/// @brief True if clutter filter processing is successful.
|
||||||
bool success;
|
bool success;
|
||||||
|
|
||||||
|
/// @brief FFTW plans for clutter filter processing.
|
||||||
|
/// @{
|
||||||
fftw_plan fftX, fftY, fftA, fftB, fftFiltX, fftFiltW, fftFilt;
|
fftw_plan fftX, fftY, fftA, fftB, fftFiltX, fftFiltW, fftFilt;
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// @brief FFTW storage for clutter filter processing.
|
||||||
|
/// @{
|
||||||
std::complex<double> *dataX, *dataY, *dataOutX, *dataOutY, *dataA, *dataB, *filtX, *filtW, *filt;
|
std::complex<double> *dataX, *dataY, *dataOutX, *dataOutY, *dataA, *dataB, *filtX, *filtW, *filt;
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// @brief Deque storage for clutter filter processing.
|
||||||
|
/// @{
|
||||||
std::deque<std::complex<double>> xData, yData;
|
std::deque<std::complex<double>> xData, yData;
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// @brief Autocorrelation toeplitz matrix.
|
||||||
arma::cx_mat A;
|
arma::cx_mat A;
|
||||||
arma::cx_vec a, b, w;
|
|
||||||
|
|
||||||
|
/// @brief Autocorrelation vector.
|
||||||
|
arma::cx_vec a;
|
||||||
|
|
||||||
|
/// @brief Cross-correlation vector.
|
||||||
|
arma::cx_vec b;
|
||||||
|
|
||||||
|
/// @brief Weights vector.
|
||||||
|
arma::cx_vec w;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/// @brief Constructor.
|
||||||
|
/// @param delayMin Minimum clutter filter delay (bins).
|
||||||
|
/// @param delayMax Maximum clutter filter delay (bins).
|
||||||
|
/// @param nSamples Number of samples per CPI.
|
||||||
|
/// @return The object.
|
||||||
WienerHopf(int32_t delayMin, int32_t delayMax, uint32_t nSamples);
|
WienerHopf(int32_t delayMin, int32_t delayMax, uint32_t nSamples);
|
||||||
|
|
||||||
|
/// @brief Destructor.
|
||||||
|
/// @return Void.
|
||||||
~WienerHopf();
|
~WienerHopf();
|
||||||
|
|
||||||
|
/// @brief Implement the clutter filter.
|
||||||
|
/// @param x Reference samples.
|
||||||
|
/// @param y Surveillance samples.
|
||||||
|
/// @return True if clutter filter successful.
|
||||||
bool process(IqData *x, IqData *y);
|
bool process(IqData *x, IqData *y);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue