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)
132 return {
vec / dist, dist};
165 denominator *= dist * dist;
168 return numerator / denominator;
193 return numerator / denominator;
222 return 2.0 *
PI *
timing->getFreqOffset() * time +
timing->getPhaseOffset();
236 if (phase_noise_lookup ==
nullptr)
242 if (phase_noise_lookup ==
nullptr)
270 return 10.0 * std::log10(
watts * 1000.0);
285 return 10.0 * std::log10(
watts);
318 source.
segment_start = std::numeric_limits<RealType>::lowest();
377 const auto triangle_index =
static_cast<std::size_t
>(std::floor(
delta / source.
triangle_period));
487 if (waveform ==
nullptr)
493 return waveform->
getPower() * (fmcw->getChirpDuration() / fmcw->getChirpPeriod());
523 if ((time <= start_time) || (samples.size() == 1) || (dt <= 0.0))
525 return samples.front();
532 return samples.back();
548 lookup.dt = sample_rate > 0.0 ? (1.0 / sample_rate) : 1.0;
550 const auto sample_count =
551 static_cast<std::size_t
>(std::ceil((
lookup.end_time -
lookup.start_time) /
lookup.dt) + 1.0);
555 for (
const auto&
timing : timings)
568 if (
lookup.start_time > 0.0)
577 "CW phase-noise lookup for timing '{}' allocates {} bytes; large scenarios need chunked "
581 buffer.samples.resize(sample_count);
582 std::ranges::generate(
buffer.samples, [&] { return timing_clone->getNextSample(); });
597 const auto it = buffers.find(
timing->getId());
598 if (
it == buffers.end())
602 return it->second.sampleAt(time);
636 LOG(Level::INFO,
"Transmitter or Receiver too close to Target for accurate simulation");
659 const bool no_loss =
recv->checkFlag(Receiver::RecvFlag::FLAG_NOPROPLOSS);
680 LOG(Level::INFO,
"Transmitter or Receiver too close for accurate simulation");
696 const bool no_loss =
recv->checkFlag(Receiver::RecvFlag::FLAG_NOPROPLOSS);
716 if (
trans ==
nullptr)
723 if (
trans->getPlatform() ==
recv->getPlatform())
753 const bool no_loss =
recv->checkFlag(Receiver::RecvFlag::FLAG_NOPROPLOSS);
797 if (
trans ==
nullptr)
803 if (
trans->getPlatform() ==
targ->getPlatform() ||
recv->getPlatform() ==
targ->getPlatform())
842 const bool no_loss =
recv->checkFlag(Receiver::RecvFlag::FLAG_NOPROPLOSS);
881 if (
targ !=
nullptr &&
882 (
targ->getPlatform() ==
trans->getPlatform() ||
targ->getPlatform() ==
recv->getPlatform()))
885 "Skipping reflected path calculation for Target {} co-located with Transmitter {} or Receiver {}",
897 LOG(Level::FATAL,
"No time points are available for execution!");
898 throw std::runtime_error(
"No time points are available for execution!");
929 LOG(Level::INFO,
"Receiver or Transmitter too close for accurate simulation");
938 struct PreviewTransmitterContext
946 struct PreviewReceiverContext
956 return PreviewTransmitterContext{.transmitter =
transmitter,
965 return PreviewReceiverContext{.receiver =
receiver,
973 for (
const auto&
target : world.getTargets())
990 .source_id =
tx_ctx.transmitter.getId(),
991 .dest_id =
target->getId(),
992 .origin_id =
tx_ctx.transmitter.getId()});
999 for (
const auto&
target : world.getTargets())
1027 .source_id =
tx_ctx.transmitter.getId(),
1028 .dest_id =
target->getId(),
1029 .origin_id =
tx_ctx.transmitter.getId(),
1035 void addDirectLink(std::vector<PreviewLink>& links,
const PreviewTransmitterContext&
tx_ctx,
1038 if (
rx_ctx.receiver.checkFlag(Receiver::RecvFlag::FLAG_NODIRECT))
1060 .source_id =
tx_ctx.transmitter.getId(),
1061 .dest_id =
rx_ctx.receiver.getId(),
1062 .origin_id =
tx_ctx.transmitter.getId()});
1069 for (
const auto&
target : world.getTargets())
1100 .source_id =
target->getId(),
1101 .dest_id =
rx_ctx.receiver.getId(),
1102 .origin_id =
tx_ctx.transmitter.getId(),
1111 if (
tx_ctx.transmitter.getAttached() == &
rx_ctx.receiver)
1124 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.
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 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.
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 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.
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.