FERS 0.1.0
The Flexible Extensible Radar Simulator
Loading...
Searching...
No Matches
fers_signal::Signal Class Reference

Class for handling radar waveform signal data. More...

#include "radar_signal.h"

+ Inheritance diagram for fers_signal::Signal:

Public Member Functions

virtual ~Signal ()=default
 
 Signal ()=default
 
 Signal (const Signal &)=delete
 
Signaloperator= (const Signal &)=delete
 
 Signal (Signal &&)=default
 
Signaloperator= (Signal &&)=default
 
void clear () noexcept
 Clears the internal signal data.
 
void load (std::span< const ComplexType > inData, unsigned samples, RealType sampleRate)
 Loads complex radar waveform data.
 
RealType getRate () const noexcept
 Gets the sample rate of the signal.
 
unsigned getSampleCount () const noexcept
 Gets the number of native samples held by this signal.
 
virtual std::vector< ComplexTyperender (const std::vector< interp::InterpPoint > &points, unsigned &size, double fracWinDelay) const
 Renders the signal data based on interpolation points.
 
virtual std::vector< ComplexTyperenderSlice (const std::vector< interp::InterpPoint > &points, RealType outputStartTime, RealType outputSampleRate, std::size_t sampleCount, RealType fracWinDelay) const
 Renders a bounded absolute-time slice on the requested output grid.
 
virtual bool isFmcwFamily () const noexcept
 Returns true when this signal belongs to the FMCW waveform family.
 

Detailed Description

Class for handling radar waveform signal data.

Definition at line 52 of file radar_signal.h.

Constructor & Destructor Documentation

◆ ~Signal()

virtual fers_signal::Signal::~Signal ( )
virtualdefault

◆ Signal() [1/3]

fers_signal::Signal::Signal ( )
default

◆ Signal() [2/3]

fers_signal::Signal::Signal ( const Signal )
delete

◆ Signal() [3/3]

fers_signal::Signal::Signal ( Signal &&  )
default

Member Function Documentation

◆ clear()

void fers_signal::Signal::clear ( )
noexcept

Clears the internal signal data.

Definition at line 232 of file radar_signal.cpp.

233 {
234 _size = 0;
235 _rate = 0;
236 }

Referenced by load().

+ Here is the caller graph for this function:

◆ getRate()

RealType fers_signal::Signal::getRate ( ) const
noexcept

Gets the sample rate of the signal.

Returns
The sample rate of the signal.

Definition at line 86 of file radar_signal.h.

86{ return _rate; }

◆ getSampleCount()

unsigned fers_signal::Signal::getSampleCount ( ) const
noexcept

Gets the number of native samples held by this signal.

Definition at line 89 of file radar_signal.h.

89{ return _size; }

◆ isFmcwFamily()

virtual bool fers_signal::Signal::isFmcwFamily ( ) const
virtualnoexcept

Returns true when this signal belongs to the FMCW waveform family.

Reimplemented in fers_signal::FmcwChirpSignal, and fers_signal::FmcwTriangleSignal.

Definition at line 109 of file radar_signal.h.

109{ return false; }

◆ load()

void fers_signal::Signal::load ( std::span< const ComplexType inData,
unsigned  samples,
RealType  sampleRate 
)

Loads complex radar waveform data.

Parameters
inDataThe input span of complex signal data.
samplesThe number of samples in the input data.
sampleRateThe sample rate of the input data.

Definition at line 238 of file radar_signal.cpp.

239 {
240 clear();
241 const unsigned ratio = params::oversampleRatio();
242 const auto oversampled_samples = static_cast<std::size_t>(samples) * static_cast<std::size_t>(ratio);
243 if (oversampled_samples > std::numeric_limits<unsigned>::max())
244 {
245 throw std::overflow_error("Oversampled signal sample count exceeds unsigned range");
246 }
247 _data.resize(oversampled_samples);
248 _size = static_cast<unsigned>(oversampled_samples);
249 _rate = sampleRate * static_cast<RealType>(ratio);
250
251 if (ratio == 1)
252 {
253 std::ranges::copy(inData, _data.begin());
254 }
255 else
256 {
257 upsample(inData, samples, _data);
258 }
259 }
void clear() noexcept
Clears the internal signal data.
double RealType
Type for real numbers.
Definition config.h:27
void upsample(const std::span< const ComplexType > in, const unsigned size, std::span< ComplexType > out)
Upsamples a complex waveform with zero-stuffing followed by Blackman FIR filtering.
unsigned oversampleRatio() noexcept
Get the oversampling ratio.
Definition parameters.h:151
math::Vec3 max

References clear(), max, params::oversampleRatio(), and fers_signal::upsample().

+ Here is the call graph for this function:

◆ operator=() [1/2]

Signal & fers_signal::Signal::operator= ( const Signal )
delete

◆ operator=() [2/2]

Signal & fers_signal::Signal::operator= ( Signal &&  )
default

◆ render()

std::vector< ComplexType > fers_signal::Signal::render ( const std::vector< interp::InterpPoint > &  points,
unsigned size,
double  fracWinDelay 
) const
virtual

Renders the signal data based on interpolation points.

Parameters
pointsA vector of interpolation points used to render the signal.
sizeReference to store the size of the rendered data.
fracWinDelayFractional window delay to apply during rendering.
Returns
A vector of rendered complex signal data.

Reimplemented in fers_signal::CwSignal, fers_signal::FmcwChirpSignal, and fers_signal::FmcwTriangleSignal.

Definition at line 261 of file radar_signal.cpp.

263 {
264 size = _size;
265 if (points.empty())
266 {
267 return std::vector<ComplexType>(_size);
268 }
269 return renderSlice(points, points.front().time, _rate, _size, fracWinDelay);
270 }
virtual std::vector< ComplexType > renderSlice(const std::vector< interp::InterpPoint > &points, RealType outputStartTime, RealType outputSampleRate, std::size_t sampleCount, RealType fracWinDelay) const
Renders a bounded absolute-time slice on the requested output grid.

References max, and renderSlice().

+ Here is the call graph for this function:

◆ renderSlice()

std::vector< ComplexType > fers_signal::Signal::renderSlice ( const std::vector< interp::InterpPoint > &  points,
RealType  outputStartTime,
RealType  outputSampleRate,
std::size_t  sampleCount,
RealType  fracWinDelay 
) const
virtual

Renders a bounded absolute-time slice on the requested output grid.

Definition at line 272 of file radar_signal.cpp.

275 {
276 auto out = std::vector<ComplexType>(sampleCount);
277 if (_size == 0 || _rate <= 0.0 || outputSampleRate <= 0.0 || points.empty())
278 {
279 return out;
280 }
281
282 const RealType timestep = 1.0 / outputSampleRate;
283 const int filt_length = static_cast<int>(params::renderFilterLength());
285
286 auto iter = points.begin();
287 auto next = points.size() > 1 ? std::next(iter) : iter;
288 const RealType idelay = std::round(_rate * iter->delay);
290
291 for (std::size_t i = 0; i < sampleCount; ++i)
292 {
293 while (sample_time > next->time && next != iter)
294 {
295 iter = next;
296 if (std::next(next) != points.end())
297 {
298 ++next;
299 }
300 else
301 {
302 break;
303 }
304 }
305
306 auto [amplitude, phase, fdelay, i_sample_unwrap] =
307 calculateWeightsAndDelays(iter, next, sample_time, idelay, fracWinDelay);
308 const RealType native_position = (sample_time - points.front().time) * _rate;
309 const auto source_index = static_cast<int>(std::floor(native_position));
312 {
313 source_fraction = 0.0;
314 }
315
317 const auto delay_unwrap = static_cast<int>(std::floor(combined_delay));
318 fdelay = combined_delay - static_cast<RealType>(delay_unwrap);
320
321 const auto& filt = interp.getFilter(fdelay);
322 const ComplexType accum =
323 performConvolution(source_index, filt.data(), filt_length, amplitude, i_sample_unwrap);
324 out[i] = std::exp(ComplexType(0.0, 1.0) * phase) * accum;
325
327 }
328
329 return out;
330 }
static InterpFilter & getInstance() noexcept
Retrieves the singleton instance of the InterpFilter class.
std::complex< RealType > ComplexType
Type for complex numbers.
Definition config.h:35
unsigned renderFilterLength() noexcept
Get the render filter length.
Definition parameters.h:139

References interp::InterpFilter::getInstance(), max, and params::renderFilterLength().

Referenced by render().

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

The documentation for this class was generated from the following files: