23#include <unordered_map>
70 tracker.triangle_initialized =
true;
76 tracker.triangle_phi_base = 0.0;
91 if (
tracker.triangle_phi_base >= 2.0 *
PI)
95 if (
tracker.triangle_phi_base < 0.0)
111 struct StreamingWaveformEvaluation
139 return {
vec / dist, dist};
172 denominator *= dist * dist;
175 return numerator / denominator;
200 return numerator / denominator;
229 return 2.0 *
PI *
timing->getFreqOffset() * time +
timing->getPhaseOffset();
243 if (phase_noise_lookup ==
nullptr)
249 if (phase_noise_lookup ==
nullptr)
277 return 10.0 * std::log10(
watts * 1000.0);
292 return 10.0 * std::log10(
watts);
325 source.
segment_start = std::numeric_limits<RealType>::lowest();
384 const auto triangle_index =
static_cast<std::size_t
>(std::floor(
delta / source.
triangle_period));
457 StreamingWaveformEvaluation&
eval)
492 if (source.
sfcw ==
nullptr)
497 if (!
step.has_value() ||
step->rf_frequency <= 0.0)
501 eval.rf_frequency =
step->rf_frequency;
526 if (waveform ==
nullptr)
532 return waveform->
getPower() * (fmcw->getChirpDuration() / fmcw->getChirpPeriod());
562 if ((time <= start_time) || (samples.size() == 1) || (dt <= 0.0))
564 return samples.front();
571 return samples.back();
587 lookup.dt = sample_rate > 0.0 ? (1.0 / sample_rate) : 1.0;
589 const auto sample_count =
590 static_cast<std::size_t
>(std::ceil((
lookup.end_time -
lookup.start_time) /
lookup.dt) + 1.0);
594 for (
const auto&
timing : timings)
607 if (
lookup.start_time > 0.0)
616 "CW phase-noise lookup for timing '{}' allocates {} bytes; large scenarios need chunked "
620 buffer.samples.resize(sample_count);
621 std::ranges::generate(
buffer.samples, [&] { return timing_clone->getNextSample(); });
636 const auto it = buffers.find(
timing->getId());
637 if (
it == buffers.end())
641 return it->second.sampleAt(time);
675 LOG(Level::INFO,
"Transmitter or Receiver too close to Target for accurate simulation");
698 const bool no_loss =
recv->checkFlag(Receiver::RecvFlag::FLAG_NOPROPLOSS);
719 LOG(Level::INFO,
"Transmitter or Receiver too close for accurate simulation");
735 const bool no_loss =
recv->checkFlag(Receiver::RecvFlag::FLAG_NOPROPLOSS);
755 if (
trans ==
nullptr)
762 if (
trans->getPlatform() ==
recv->getPlatform())
781 StreamingWaveformEvaluation
eval;
793 const bool no_loss =
recv->checkFlag(Receiver::RecvFlag::FLAG_NOPROPLOSS);
813 StreamingWaveformEvaluation
eval;
819 if (std::abs(
eval.envelope) > 0.0)
829 StreamingWaveformEvaluation
eval;
854 if (
trans ==
nullptr)
860 if (
trans->getPlatform() ==
targ->getPlatform() ||
recv->getPlatform() ==
targ->getPlatform())
883 StreamingWaveformEvaluation
eval;
900 const bool no_loss =
recv->checkFlag(Receiver::RecvFlag::FLAG_NOPROPLOSS);
934 if (
targ !=
nullptr &&
935 (
targ->getPlatform() ==
trans->getPlatform() ||
targ->getPlatform() ==
recv->getPlatform()))
938 "Skipping reflected path calculation for Target {} co-located with Transmitter {} or Receiver {}",
950 LOG(Level::FATAL,
"No time points are available for execution!");
951 throw std::runtime_error(
"No time points are available for execution!");
982 LOG(Level::INFO,
"Receiver or Transmitter too close for accurate simulation");
991 struct PreviewTransmitterContext
999 struct PreviewReceiverContext
1009 return PreviewTransmitterContext{.transmitter =
transmitter,
1018 return PreviewReceiverContext{.receiver =
receiver,
1026 for (
const auto&
target : world.getTargets())
1043 .source_id =
tx_ctx.transmitter.getId(),
1044 .dest_id =
target->getId(),
1045 .origin_id =
tx_ctx.transmitter.getId()});
1052 for (
const auto&
target : world.getTargets())
1080 .source_id =
tx_ctx.transmitter.getId(),
1081 .dest_id =
target->getId(),
1082 .origin_id =
tx_ctx.transmitter.getId(),
1088 void addDirectLink(std::vector<PreviewLink>& links,
const PreviewTransmitterContext&
tx_ctx,
1091 if (
rx_ctx.receiver.checkFlag(Receiver::RecvFlag::FLAG_NODIRECT))
1113 .source_id =
tx_ctx.transmitter.getId(),
1114 .dest_id =
rx_ctx.receiver.getId(),
1115 .origin_id =
tx_ctx.transmitter.getId()});
1122 for (
const auto&
target : world.getTargets())
1153 .source_id =
target->getId(),
1154 .dest_id =
rx_ctx.receiver.getId(),
1155 .origin_id =
tx_ctx.transmitter.getId(),
1164 if (
tx_ctx.transmitter.getAttached() == &
rx_ctx.receiver)
1177 std::vector<PreviewLink> links;
const Transmitter & transmitter
const Receiver & receiver
Header for radar channel propagation and interaction models.
The World class manages the simulator environment.
const std::vector< std::unique_ptr< radar::Transmitter > > & getTransmitters() const noexcept
Retrieves the list of radar transmitters.
const std::vector< std::unique_ptr< radar::Receiver > > & getReceivers() const noexcept
Retrieves the list of radar receivers.
Class representing a radar signal with associated properties.
bool isFmcwTriangle() const noexcept
Returns true when this signal is an FMCW triangular modulation signal.
RealType getCarrier() const noexcept
Gets the carrier frequency of the radar signal.
const class FmcwChirpSignal * getFmcwChirpSignal() const noexcept
Gets the FMCW chirp implementation, if this signal owns one.
RealType getPower() const noexcept
Gets the power of the radar signal.
ComplexType sampleAt(RealType time_since_start) const noexcept
Samples the finite stored complex envelope using the render interpolation filter.
std::optional< StepState > activeStepAt(RealType time_since_segment_start, RealType carrier_frequency) const noexcept
Returns the active step for a time since the segment start.
A class representing a vector in spherical coordinates.
A class representing a vector in rectangular coordinates.
RealType length() const noexcept
Calculates the length (magnitude) of the vector.
math::Vec3 getPosition(const RealType time) const
Retrieves the position of the object.
Represents a radar system on a platform.
Manages radar signal reception and response processing.
bool checkFlag(RecvFlag flag) const noexcept
Checks if a specific flag is set.
Base class for radar targets.
Represents a radar transmitter system.
fers_signal::RadarSignal * getSignal() const noexcept
Retrieves the radar signal currently being transmitted.
Exception thrown when a range calculation fails, typically due to objects being too close.
Represents a timing source for simulation.
double RealType
Type for real numbers.
constexpr RealType EPSILON
Machine epsilon for real numbers.
std::complex< RealType > ComplexType
Type for complex numbers.
constexpr RealType PI
Mathematical constant π (pi).
Classes and operations for 3D geometry.
Defines a structure to store interpolation point data for signal processing.
Header file for the logging system.
ActiveStreamingSource makeActiveSource(const radar::Transmitter *const tx, const RealType segment_start, const RealType segment_end)
Builds an active-source cache from a streaming transmitter and segment bounds.
RealType simSamplingRate() noexcept
Get the simulation sampling rate.
RealType rate() noexcept
Get the rendering sample rate.
RealType startTime() noexcept
Get the start time for the simulation.
RealType boltzmannK() noexcept
Get the Boltzmann constant.
unsigned oversampleRatio() noexcept
Get the oversampling ratio.
RealType c() noexcept
Get the speed of light.
ComplexType calculateStreamingDirectPathContribution(const core::ActiveStreamingSource &source, const Receiver *recv, const RealType timeK, const CwPhaseNoiseLookup *const phase_noise_lookup, core::FmcwChirpBoundaryTracker *const chirp_tracker, const StreamingTimingPhaseMode timing_phase_mode)
Calculates a direct-path contribution from a cached streaming source.
@ DirectTxRx
Interference path.
@ Monostatic
Combined Tx/Rx path.
@ BistaticTgtRx
Scattered path.
@ BistaticTxTgt
Illuminator path.
ComplexType calculateReflectedPathContribution(const Transmitter *trans, const Receiver *recv, const Target *targ, const RealType timeK, const CwPhaseNoiseLookup *const phase_noise_lookup)
Calculates the complex envelope contribution for a reflected path (Tx -> Tgt -> Rx) at a specific tim...
@ Weak
SNR < 0 dB (Geometric line of sight, but below noise floor)
void solveReDirect(const Transmitter *trans, const Receiver *recv, const std::chrono::duration< RealType > &time, const RadarSignal *wave, ReResults &results)
Solves the radar equation for a direct path (Tx -> Rx).
bool calculateStreamingReferenceSample(const core::ActiveStreamingSource &source, const RealType timeK, core::FmcwChirpBoundaryTracker *const chirp_tracker, ComplexType &sample_out)
Evaluates the complete complex reference envelope, including file-backed amplitude modulation.
bool calculateStreamingReferencePhase(const core::ActiveStreamingSource &source, const RealType timeK, core::FmcwChirpBoundaryTracker *const chirp_tracker, RealType &phase_out)
Evaluates a receive-time streaming waveform phase for receiver LO/dechirp references.
StreamingTimingPhaseMode
Selects how timing phase noise is applied to streaming channel contributions.
@ TransmitterOnly
Incoming RF/baseband signal before receiver LO subtraction.
@ None
Ignore timing phase noise entirely.
void solveRe(const Transmitter *trans, const Receiver *recv, const Target *targ, const std::chrono::duration< RealType > &time, const RadarSignal *wave, ReResults &results)
Solves the bistatic radar equation for a reflected path (Tx -> Tgt -> Rx).
ComplexType calculateStreamingReflectedPathContribution(const core::ActiveStreamingSource &source, const Receiver *recv, const Target *targ, const RealType timeK, const CwPhaseNoiseLookup *const phase_noise_lookup, core::FmcwChirpBoundaryTracker *const chirp_tracker, const StreamingTimingPhaseMode timing_phase_mode)
Calculates a reflected-path contribution from a cached streaming source.
ComplexType calculateDirectPathContribution(const Transmitter *trans, const Receiver *recv, const RealType timeK, const CwPhaseNoiseLookup *const phase_noise_lookup)
Calculates the complex envelope contribution for a direct propagation path (Tx -> Rx) at a specific t...
std::vector< PreviewLink > calculatePreviewLinks(const core::World &world, const RealType time)
Calculates all visual links for the current world state at a specific time.
std::unique_ptr< serial::Response > calculateResponse(const Transmitter *trans, const Receiver *recv, const RadarSignal *signal, const RealType startTime, const Target *targ)
Creates a Response object by simulating a signal's interaction over its duration.
Defines the Parameters struct and provides methods for managing simulation parameters.
Defines the Radar class and associated functionality.
Classes for handling radar waveforms and signals.
Radar Receiver class for managing signal reception and response handling.
Classes for managing radar signal responses.
Cached description of an active streaming transmitter segment.
RealType s_pi_alpha
Cached signed pi-scaled FMCW chirp-rate factor.
RealType triangle_period
Cached full triangle period in seconds.
RealType amplitude
Cached emitted signal amplitude.
RealType carrier_freq
Cached carrier frequency in hertz.
const fers_signal::SteppedFrequencySignal * sfcw
Stable pointer to the stepped-frequency waveform, if any.
RealType two_pi_f0
Cached two-pi carrier angular frequency factor.
RealType neg_pi_alpha
Triangle down-leg quadratic coefficient.
RealType two_pi_f0_plus_B
Triangle down-leg linear coefficient.
RealType mod_phi_tri
Triangle period phase increment modulo 2*pi.
RealType mod_phi_up
Triangle leg phase increment modulo 2*pi.
RealType segment_start
Segment start time in seconds.
RealType file_duration
Duration of the finite file waveform in seconds.
RealType pi_alpha
Triangle up-leg quadratic coefficient.
const radar::Transmitter * transmitter
Transmitter active during this segment.
RealType chirp_duration
Cached FMCW chirp duration in seconds.
RealType chirp_period
Cached FMCW chirp period in seconds.
StreamingWaveformKind kind
Cached streaming waveform shape.
const fers_signal::FileSignal * file
Stable pointer to the finite sampled waveform, if any.
std::optional< std::size_t > chirp_count
Optional finite chirp count for the segment.
std::optional< std::size_t > triangle_count
Optional finite triangle count for the segment.
RealType segment_end
Segment end time in seconds.
Tracks the current FMCW chirp boundary for a streaming path.
Stores data for an interpolation point.
Sampled phase-noise buffer for one timing source.
RealType sampleAt(RealType time) const noexcept
Returns the interpolated phase-noise sample at the specified time.
Lookup table for CW phase noise across timing sources.
static CwPhaseNoiseLookup build(std::span< const std::shared_ptr< timing::Timing > > timings, RealType start_time, RealType end_time)
Builds a phase-noise lookup for the requested timing sources and time range.
RealType end_time
Lookup end time in seconds.
RealType start_time
Lookup start time in seconds.
RealType sample(const timing::Timing *timing, RealType time) const noexcept
Samples phase noise for one timing source at the specified time.
RealType phaseDifference(const timing::Timing *rx_timing, RealType rx_time, const timing::Timing *tx_timing, RealType tx_time) const noexcept
Computes receiver-minus-transmitter phase noise at two propagation times.
Stores the intermediate results of a radar equation calculation for a single time point.
Defines classes for radar targets and their Radar Cross-Section (RCS) models.
Timing source for simulation objects.
Header file for the Transmitter class in the radar namespace.
Header file for the World class in the simulator.