45 throw std::runtime_error(
"Unsupported FMCW chirp direction '" + std::string(
direction) +
"'.");
58 _chirp_bandwidth(chirp_bandwidth), _chirp_duration(chirp_duration), _chirp_period(chirp_period),
59 _start_frequency_offset(start_frequency_offset), _chirp_count(chirp_count),
60 _chirp_rate(chirp_bandwidth / chirp_duration), _direction(
direction)
64 std::optional<std::size_t>
73 if (_chirp_count.has_value() &&
chirp_index >= *_chirp_count)
88 std::optional<RealType>
114 const RealType start_frequency_offset,
115 std::optional<std::size_t> triangle_count) :
116 _chirp_bandwidth(chirp_bandwidth), _chirp_duration(chirp_duration),
117 _start_frequency_offset(start_frequency_offset), _triangle_count(triangle_count),
118 _chirp_rate(chirp_bandwidth / chirp_duration), _triangle_period(2.0 * chirp_duration),
119 _delta_phi_up(2.0 *
PI * start_frequency_offset * chirp_duration +
120 PI * _chirp_rate * chirp_duration * chirp_duration)
131 const auto triangle_index =
static_cast<std::size_t
>(std::floor(
triangle_time / _triangle_period));
136 static_cast<RealType>(triangle_index) * 2.0 * _delta_phi_up + (
down_leg ? _delta_phi_up : 0.0);
139 return phi_base + 2.0 *
PI * _start_frequency_offset *
u +
PI * _chirp_rate *
u *
u;
141 return phi_base + 2.0 *
PI * (_start_frequency_offset + _chirp_bandwidth) *
u -
PI * _chirp_rate *
u *
u;
144 std::optional<RealType>
153 if (_triangle_count.has_value() && triangle_index >= *_triangle_count)
181 throw std::runtime_error(
"Signal is empty");
191 std::ranges::for_each(
data, [
scale](
auto& value) { value *=
scale; });
203 std::ranges::for_each(
data, [
scale](
auto& value) { value *=
scale; });
242 const auto oversampled_samples =
static_cast<std::size_t
>(samples) *
static_cast<std::size_t
>(ratio);
245 throw std::overflow_error(
"Oversampled signal sample count exceeds unsigned range");
249 _rate = sampleRate *
static_cast<RealType>(ratio);
253 std::ranges::copy(
inData, _data.begin());
261 std::vector<ComplexType>
Signal::render(
const std::vector<interp::InterpPoint>& points,
unsigned&
size,
267 return std::vector<ComplexType>(_size);
276 auto out = std::vector<ComplexType>(sampleCount);
277 if (_size == 0 || _rate <= 0.0 ||
outputSampleRate <= 0.0 || points.empty())
286 auto iter = points.begin();
287 auto next = points.size() > 1 ? std::next(
iter) :
iter;
291 for (std::size_t i = 0; i < sampleCount; ++i)
296 if (std::next(next) != points.end())
332 std::tuple<RealType, RealType, RealType, int>
333 Signal::calculateWeightsAndDelays(
const std::vector<interp::InterpPoint>::const_iterator
iter,
334 const std::vector<interp::InterpPoint>::const_iterator next,
340 const RealType amplitude = std::lerp(std::sqrt(
iter->power), std::sqrt(next->power),
bw);
353 const int start = std::max(-
filtLength / 2, -i);
354 const int end = std::min(
filtLength / 2,
static_cast<int>(_size) - i);
358 for (
int j = start;
j < end; ++
j)
Thread-safe Meyers singleton for generating unique object IDs.
Continuous-wave signal implementation.
std::vector< ComplexType > render(const std::vector< interp::InterpPoint > &points, unsigned &size, RealType fracWinDelay) const override
Renders the signal data.
FMCW linear chirp signal implementation.
std::optional< RealType > instantaneousBasebandPhase(RealType time_since_segment_start) const noexcept
Computes instantaneous baseband phase at a time since segment start.
RealType basebandPhaseForChirpTime(RealType chirp_time) const noexcept
Computes baseband phase for a time inside a chirp.
std::vector< ComplexType > render(const std::vector< interp::InterpPoint > &points, unsigned &size, RealType fracWinDelay) const override
Renders an FMCW waveform from interpolation points.
FmcwChirpSignal(RealType chirp_bandwidth, RealType chirp_duration, RealType chirp_period, RealType start_frequency_offset=0.0, std::optional< std::size_t > chirp_count=std::nullopt, FmcwChirpDirection direction=FmcwChirpDirection::Up)
Constructs an FMCW chirp signal with timing and sweep parameters.
std::optional< std::size_t > activeChirpIndexAt(RealType time_since_segment_start) const noexcept
Returns the active chirp index for a time since the segment start.
FMCW symmetric triangular modulation signal implementation.
RealType basebandPhaseForTriangleTime(RealType triangle_time) const noexcept
Computes baseband phase at a time since the triangle train start.
std::optional< RealType > instantaneousBasebandPhase(RealType time_since_segment_start) const noexcept
Computes instantaneous baseband phase at a time since segment start.
std::vector< ComplexType > render(const std::vector< interp::InterpPoint > &points, unsigned &size, RealType fracWinDelay) const override
Renders an FMCW waveform from interpolation points.
FmcwTriangleSignal(RealType chirp_bandwidth, RealType chirp_duration, RealType start_frequency_offset=0.0, std::optional< std::size_t > triangle_count=std::nullopt)
Constructs an FMCW triangular modulation signal.
RadarSignal(std::string name, RealType power, RealType carrierfreq, RealType length, std::unique_ptr< Signal > signal, const SimId id=0)
Constructs a RadarSignal object.
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.
const class FmcwTriangleSignal * getFmcwTriangleSignal() const noexcept
Gets the FMCW triangle implementation, if this signal owns one.
std::vector< ComplexType > render(const std::vector< interp::InterpPoint > &points, unsigned &size, RealType fracWinDelay) const
Renders the radar signal.
bool isFmcwTriangle() const noexcept
Returns true when this signal is an FMCW triangular modulation signal.
bool isFmcwFamily() const noexcept
Returns true when this signal belongs to the FMCW waveform family.
bool isFmcwChirp() const noexcept
Returns true when this signal is an FMCW linear chirp signal.
bool isCw() const noexcept
Returns true when this signal is a continuous-wave signal.
const class FmcwChirpSignal * getFmcwChirpSignal() const noexcept
Gets the FMCW chirp implementation, if this signal owns one.
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.
void clear() noexcept
Clears the internal signal data.
void load(std::span< const ComplexType > inData, unsigned samples, RealType sampleRate)
Loads complex radar waveform data.
virtual std::vector< ComplexType > render(const std::vector< interp::InterpPoint > &points, unsigned &size, double fracWinDelay) const
Renders the signal data based on interpolation points.
static InterpFilter & getInstance() noexcept
Retrieves the singleton instance of the InterpFilter class.
double RealType
Type for real numbers.
std::complex< RealType > ComplexType
Type for complex numbers.
constexpr RealType PI
Mathematical constant π (pi).
Header file for Digital Signal Processing (DSP) filters and upsampling/downsampling functionality.
Interpolation filter implementation using Kaiser windowing.
Defines a structure to store interpolation point data for signal processing.
FmcwChirpDirection parseFmcwChirpDirection(const std::string_view direction)
Parses a schema chirp direction token.
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.
std::string_view fmcwChirpDirectionToken(const FmcwChirpDirection direction) noexcept
Converts a chirp direction to the schema token.
FmcwChirpDirection
Sweep direction for a linear FMCW chirp.
@ Down
Instantaneous baseband frequency decreases over the chirp.
@ Up
Instantaneous baseband frequency increases over the chirp.
unsigned oversampleRatio() noexcept
Get the oversampling ratio.
unsigned renderFilterLength() noexcept
Get the render filter length.
Defines the Parameters struct and provides methods for managing simulation parameters.
Classes for handling radar waveforms and signals.
uint64_t SimId
64-bit Unique Simulation ID.
ObjectType
Categorizes objects for ID generation.