FERS 1.0.0
The Flexible Extensible Radar Simulator
Loading...
Searching...
No Matches
fers_signal Namespace Reference

Classes

class  CwSignal
 
class  DecadeUpsampler
 Implements a specialized upsampler with a fixed upsampling factor of 10. More...
 
class  DspFilter
 Abstract base class for digital filters. More...
 
class  FirFilter
 Implements a Finite Impulse Response (FIR) filter. More...
 
class  IirFilter
 Implements an Infinite Impulse Response (IIR) filter. More...
 
class  RadarSignal
 Class representing a radar signal with associated properties. More...
 
class  Signal
 Class for handling radar waveform signal data. More...
 

Functions

void to_json (nlohmann::json &j, const RadarSignal &rs)
 
void from_json (const nlohmann::json &j, std::unique_ptr< RadarSignal > &rs)
 
void upsample (std::span< const ComplexType > in, unsigned size, std::span< ComplexType > out)
 Upsamples a signal by a given ratio.
 
std::vector< ComplexTypedownsample (std::span< const ComplexType > in)
 Downsamples a signal by a given ratio.
 

Function Documentation

◆ downsample()

std::vector< ComplexType > fers_signal::downsample ( std::span< const ComplexType in)

Downsamples a signal by a given ratio.

Parameters
inInput span of complex samples.
Exceptions
std::invalid_argumentif the input or output spans are empty or the ratio is zero.

Definition at line 94 of file dsp_filters.cpp.

95 {
96 if (in.empty())
97 {
98 throw std::invalid_argument("Input span is empty in Downsample");
99 }
100
101 const unsigned ratio = params::oversampleRatio();
102 // TODO: Replace with a more efficient multirate downsampling implementation.
103 unsigned filt_length = 0;
104 const auto coeffs = blackmanFir(1 / static_cast<RealType>(ratio), filt_length);
105
106 std::vector tmp(in.size() + filt_length, ComplexType{0, 0});
107
108 std::ranges::copy(in, tmp.begin());
109
110 const FirFilter filt(coeffs);
111 filt.filter(tmp);
112
113 const auto downsampled_size = in.size() / ratio;
114 std::vector<ComplexType> out(downsampled_size);
115 for (unsigned i = 0; i < downsampled_size; ++i)
116 {
117 out[i] = tmp[i * ratio + filt_length / 2] / static_cast<RealType>(ratio);
118 }
119
120 return out;
121 }
double RealType
Type for real numbers.
Definition config.h:27
std::complex< RealType > ComplexType
Type for complex numbers.
Definition config.h:35
unsigned oversampleRatio() noexcept
Get the oversampling ratio.
Definition parameters.h:151

References fers_signal::FirFilter::filter(), and params::oversampleRatio().

Referenced by processing::pipeline::applyDownsamplingAndQuantization().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ from_json()

void fers_signal::from_json ( const nlohmann::json &  j,
std::unique_ptr< RadarSignal > &  rs 
)

Definition at line 312 of file json_serializer.cpp.

313 {
314 const auto name = j.at("name").get<std::string>();
315 const auto id = parse_json_id(j, "id", "waveform");
316 const auto power = j.at("power").get<RealType>();
317 const auto carrier = j.at("carrier_frequency").get<RealType>();
318
319 if (j.contains("cw"))
320 {
321 auto cw_signal = std::make_unique<CwSignal>();
322 rs = std::make_unique<RadarSignal>(name, power, carrier, params::endTime() - params::startTime(),
323 std::move(cw_signal), id);
324 }
325 else if (j.contains("pulsed_from_file"))
326 {
327 const auto& pulsed_file = j.at("pulsed_from_file");
328 const auto filename = pulsed_file.value("filename", "");
329 if (filename.empty())
330 {
331 LOG(logging::Level::WARNING, "Skipping load of file-based waveform '{}': filename is empty.", name);
332 return; // rs remains nullptr
333 }
334 rs = serial::loadWaveformFromFile(name, filename, power, carrier, id);
335 }
336 else
337 {
338 throw std::runtime_error("Unsupported waveform type in from_json for '" + name + "'");
339 }
340 }
#define LOG(level,...)
Definition logging.h:19
@ WARNING
Warning level for potentially harmful situations.
RealType endTime() noexcept
Get the end time for the simulation.
Definition parameters.h:109
RealType startTime() noexcept
Get the start time for the simulation.
Definition parameters.h:103
std::unique_ptr< RadarSignal > loadWaveformFromFile(const std::string &name, const std::string &filename, const RealType power, const RealType carrierFreq, const SimId id)
Loads a radar waveform from a file and returns a RadarSignal object.

References params::endTime(), serial::loadWaveformFromFile(), LOG, params::startTime(), and logging::WARNING.

Referenced by serial::parse_waveform_from_json().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ to_json()

void fers_signal::to_json ( nlohmann::json &  j,
const RadarSignal rs 
)

Definition at line 288 of file json_serializer.cpp.

289 {
290 j = nlohmann::json{{"id", sim_id_to_json(rs.getId())},
291 {"name", rs.getName()},
292 {"power", rs.getPower()},
293 {"carrier_frequency", rs.getCarrier()}};
294 if (dynamic_cast<const CwSignal*>(rs.getSignal()) != nullptr)
295 {
296 j["cw"] = nlohmann::json::object();
297 }
298 else
299 {
300 if (const auto& filename = rs.getFilename(); filename.has_value())
301 {
302 j["pulsed_from_file"] = {{"filename", *filename}};
303 }
304 else
305 {
306 throw std::logic_error("Attempted to serialize a file-based waveform named '" + rs.getName() +
307 "' without a source filename.");
308 }
309 }
310 }
SimId getId() const noexcept
Gets the unique ID of the radar signal.
const std::optional< std::string > & getFilename() const noexcept
Gets the filename associated with this signal.
const std::string & getName() const noexcept
Gets the name of the radar signal.
RealType getCarrier() const noexcept
Gets the carrier frequency of the radar signal.
const Signal * getSignal() const noexcept
Gets the underlying signal object.
RealType getPower() const noexcept
Gets the power of the radar signal.

References fers_signal::RadarSignal::getCarrier(), fers_signal::RadarSignal::getFilename(), fers_signal::RadarSignal::getId(), fers_signal::RadarSignal::getName(), fers_signal::RadarSignal::getPower(), and fers_signal::RadarSignal::getSignal().

+ Here is the call graph for this function:

◆ upsample()

void fers_signal::upsample ( std::span< const ComplexType in,
unsigned  size,
std::span< ComplexType out 
)

Upsamples a signal by a given ratio.

Parameters
inInput span of complex samples.
sizeSize of the input signal.
outOutput span for upsampled complex samples.
Exceptions
std::invalid_argumentif the input or output spans are empty or the ratio is zero.

Definition at line 71 of file dsp_filters.cpp.

72 {
73 const unsigned ratio = params::oversampleRatio();
74 // TODO: this would be better as a multirate upsampler
75 // This implementation is functional but suboptimal.
76 // Users requiring higher accuracy should oversample outside FERS until this is addressed.
77 unsigned filt_length;
78 const auto coeffs = blackmanFir(1 / static_cast<RealType>(ratio), filt_length);
79
80 std::vector tmp(size * ratio + filt_length, ComplexType{0.0, 0.0});
81
82 for (unsigned i = 0; i < size; ++i)
83 {
84 tmp[i * ratio] = in[i];
85 }
86
87 const FirFilter filt(coeffs);
88 filt.filter(tmp);
89
90 const auto delay = filt_length / 2;
91 std::ranges::copy_n(tmp.begin() + delay, size * ratio, out.begin());
92 }

References fers_signal::FirFilter::filter(), and params::oversampleRatio().

Referenced by fers_signal::Signal::load(), and fers_signal::DecadeUpsampler::~DecadeUpsampler().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: