FERS 0.1.0
The Flexible Extensible Radar Simulator
Loading...
Searching...
No Matches
simulation Namespace Reference

Classes

struct  CwPhaseNoiseBuffer
 Sampled phase-noise buffer for one timing source. More...
 
struct  CwPhaseNoiseLookup
 Lookup table for CW phase noise across timing sources. More...
 
struct  PreviewLink
 A calculated link segment for 3D visualization. More...
 
class  RangeError
 Exception thrown when a range calculation fails, typically due to objects being too close. More...
 
struct  ReResults
 Stores the intermediate results of a radar equation calculation for a single time point. More...
 

Enumerations

enum class  StreamingTimingPhaseMode : std::uint8_t { ReceiverRelative , TransmitterOnly , None }
 Selects how timing phase noise is applied to streaming channel contributions. More...
 
enum class  LinkType : std::uint8_t { Monostatic , BistaticTxTgt , BistaticTgtRx , DirectTxRx }
 Categorizes the visual link for rendering. More...
 
enum class  LinkQuality : std::uint8_t { Strong , Weak }
 Describes the radiometric quality of the link. More...
 

Functions

void solveRe (const radar::Transmitter *trans, const radar::Receiver *recv, const radar::Target *targ, const std::chrono::duration< RealType > &time, const fers_signal::RadarSignal *wave, ReResults &results)
 Solves the bistatic radar equation for a reflected path (Tx -> Tgt -> Rx).
 
void solveReDirect (const radar::Transmitter *trans, const radar::Receiver *recv, const std::chrono::duration< RealType > &time, const fers_signal::RadarSignal *wave, ReResults &results)
 Solves the radar equation for a direct path (Tx -> Rx).
 
ComplexType calculateDirectPathContribution (const radar::Transmitter *trans, const radar::Receiver *recv, RealType timeK, const CwPhaseNoiseLookup *phase_noise_lookup=nullptr)
 Calculates the complex envelope contribution for a direct propagation path (Tx -> Rx) at a specific time.
 
ComplexType calculateStreamingDirectPathContribution (const core::ActiveStreamingSource &source, const radar::Receiver *recv, RealType timeK, const CwPhaseNoiseLookup *phase_noise_lookup=nullptr, core::FmcwChirpBoundaryTracker *chirp_tracker=nullptr, StreamingTimingPhaseMode timing_phase_mode=StreamingTimingPhaseMode::ReceiverRelative)
 Calculates a direct-path contribution from a cached streaming source.
 
bool calculateStreamingReferencePhase (const core::ActiveStreamingSource &source, RealType timeK, core::FmcwChirpBoundaryTracker *chirp_tracker, RealType &phase_out)
 Evaluates a receive-time streaming waveform phase for receiver LO/dechirp references.
 
bool calculateStreamingReferenceSample (const core::ActiveStreamingSource &source, RealType timeK, core::FmcwChirpBoundaryTracker *chirp_tracker, ComplexType &sample_out)
 Evaluates the complete complex reference envelope, including file-backed amplitude modulation.
 
ComplexType calculateReflectedPathContribution (const radar::Transmitter *trans, const radar::Receiver *recv, const radar::Target *targ, RealType timeK, const CwPhaseNoiseLookup *phase_noise_lookup=nullptr)
 Calculates the complex envelope contribution for a reflected path (Tx -> Tgt -> Rx) at a specific time.
 
ComplexType calculateStreamingReflectedPathContribution (const core::ActiveStreamingSource &source, const radar::Receiver *recv, const radar::Target *targ, RealType timeK, const CwPhaseNoiseLookup *phase_noise_lookup=nullptr, core::FmcwChirpBoundaryTracker *chirp_tracker=nullptr, StreamingTimingPhaseMode timing_phase_mode=StreamingTimingPhaseMode::ReceiverRelative)
 Calculates a reflected-path contribution from a cached streaming source.
 
std::unique_ptr< serial::ResponsecalculateResponse (const radar::Transmitter *trans, const radar::Receiver *recv, const fers_signal::RadarSignal *signal, RealType startTime, const radar::Target *targ=nullptr)
 Creates a Response object by simulating a signal's interaction over its duration.
 
std::vector< PreviewLinkcalculatePreviewLinks (const core::World &world, RealType time)
 Calculates all visual links for the current world state at a specific time.
 

Enumeration Type Documentation

◆ LinkQuality

enum class simulation::LinkQuality : std::uint8_t
strong

Describes the radiometric quality of the link.

Enumerator
Strong 

SNR > 0 dB.

Weak 

SNR < 0 dB (Geometric line of sight, but below noise floor)

Definition at line 280 of file channel_model.h.

281 {
282 Strong, ///< SNR > 0 dB
283 Weak ///< SNR < 0 dB (Geometric line of sight, but below noise floor)
284 };
@ Weak
SNR < 0 dB (Geometric line of sight, but below noise floor)

◆ LinkType

enum class simulation::LinkType : std::uint8_t
strong

Categorizes the visual link for rendering.

Enumerator
Monostatic 

Combined Tx/Rx path.

BistaticTxTgt 

Illuminator path.

BistaticTgtRx 

Scattered path.

DirectTxRx 

Interference path.

Definition at line 268 of file channel_model.h.

269 {
270 Monostatic, ///< Combined Tx/Rx path
271 BistaticTxTgt, ///< Illuminator path
272 BistaticTgtRx, ///< Scattered path
273 DirectTxRx ///< Interference path
274 };
@ DirectTxRx
Interference path.
@ Monostatic
Combined Tx/Rx path.
@ BistaticTgtRx
Scattered path.
@ BistaticTxTgt
Illuminator path.

◆ StreamingTimingPhaseMode

Selects how timing phase noise is applied to streaming channel contributions.

Enumerator
ReceiverRelative 

Existing raw streaming convention: transmitter phase minus receiver LO phase.

TransmitterOnly 

Incoming RF/baseband signal before receiver LO subtraction.

None 

Ignore timing phase noise entirely.

Definition at line 95 of file channel_model.h.

96 {
97 ReceiverRelative, ///< Existing raw streaming convention: transmitter phase minus receiver LO phase.
98 TransmitterOnly, ///< Incoming RF/baseband signal before receiver LO subtraction.
99 None ///< Ignore timing phase noise entirely.
100 };
@ TransmitterOnly
Incoming RF/baseband signal before receiver LO subtraction.
@ ReceiverRelative
Existing raw streaming convention: transmitter phase minus receiver LO phase.

Function Documentation

◆ calculateDirectPathContribution()

ComplexType simulation::calculateDirectPathContribution ( const radar::Transmitter trans,
const radar::Receiver recv,
RealType  timeK,
const CwPhaseNoiseLookup phase_noise_lookup = nullptr 
)

Calculates the complex envelope contribution for a direct propagation path (Tx -> Rx) at a specific time.

This function is used for Continuous Wave (CW) simulations.

Parameters
transThe transmitter.
recvThe receiver.
timeKThe current simulation time.
Returns
The complex I/Q sample contribution for this path.

Definition at line 741 of file channel_model.cpp.

743 {
745 phase_noise_lookup);
746 }
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.
math::Vec3 max

References calculateStreamingDirectPathContribution(), and max.

+ Here is the call graph for this function:

◆ calculatePreviewLinks()

std::vector< PreviewLink > simulation::calculatePreviewLinks ( const core::World world,
RealType  time 
)

Calculates all visual links for the current world state at a specific time.

This function utilizes the core radar equation helpers to determine visibility, power levels, and SNR for all Tx/Rx/Target combinations. It is lightweight and does not update simulation state.

Parameters
worldThe simulation world containing radar components.
timeThe time at which to calculate geometry.
Returns
A vector of renderable links.

Definition at line 1175 of file channel_model.cpp.

1176 {
1177 std::vector<PreviewLink> links;
1178
1179 for (const auto& tx : world.getTransmitters())
1180 {
1181 if (!isComponentActive(tx->getSchedule(), time))
1182 {
1183 continue;
1184 }
1185
1186 const auto tx_ctx = makePreviewTransmitterContext(*tx, time);
1187 addIlluminatorLinks(links, tx_ctx, world, time);
1188
1189 for (const auto& rx : world.getReceivers())
1190 {
1191 if (!isComponentActive(rx->getSchedule(), time))
1192 {
1193 continue;
1194 }
1195 const auto rx_ctx = makePreviewReceiverContext(*rx, time);
1196 addReceiverLinks(links, tx_ctx, rx_ctx, world, time);
1197 }
1198 }
1199 return links;
1200 }

References core::World::getReceivers(), core::World::getTransmitters(), and max.

Referenced by fers_calculate_preview_links().

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

◆ calculateReflectedPathContribution()

ComplexType simulation::calculateReflectedPathContribution ( const radar::Transmitter trans,
const radar::Receiver recv,
const radar::Target targ,
RealType  timeK,
const CwPhaseNoiseLookup phase_noise_lookup = nullptr 
)

Calculates the complex envelope contribution for a reflected path (Tx -> Tgt -> Rx) at a specific time.

This function is used for Continuous Wave (CW) simulations.

Parameters
transThe transmitter.
recvThe receiver.
targThe target.
timeKThe current simulation time.
Returns
The complex I/Q sample contribution for this path.

Definition at line 838 of file channel_model.cpp.

841 {
843 phase_noise_lookup);
844 }
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.

References calculateStreamingReflectedPathContribution(), and max.

+ Here is the call graph for this function:

◆ calculateResponse()

std::unique_ptr< serial::Response > simulation::calculateResponse ( const radar::Transmitter trans,
const radar::Receiver recv,
const fers_signal::RadarSignal signal,
RealType  startTime,
const radar::Target targ = nullptr 
)

Creates a Response object by simulating a signal's interaction over its duration.

This function iterates over the duration of a transmitted pulse, calling the appropriate channel model function (solveRe or solveReDirect) at discrete time steps to generate a series of InterpPoints. These points capture the time-varying properties of the received signal and are collected into a Response object.

Parameters
transPointer to the transmitter.
recvPointer to the receiver.
signalPointer to the transmitted pulse signal.
startTimeThe absolute simulation time when the pulse transmission starts.
targOptional pointer to a target. If null, a direct path is simulated.
Returns
A unique pointer to the generated Response object.
Exceptions
RangeErrorIf the channel model reports an invalid geometry.
std::runtime_errorIf the simulation parameters result in zero time steps.

Definition at line 917 of file channel_model.cpp.

920 {
921 // If calculating direct path (no target) and components are co-located:
922 // 1. If explicitly attached (monostatic), skip (internal leakage handled elsewhere).
923 // 2. If independent but on the same platform, distance is 0. Far-field logic (1/R^2)
924 // diverges. We skip calculation to avoid RangeError crashes, assuming
925 // no direct coupling/interference for co-located far-field antennas.
926 if (targ == nullptr && (trans->getAttached() == recv || trans->getPlatform() == recv->getPlatform()))
927 {
928 return nullptr;
929 }
930
931 // If calculating reflected path and target is co-located with either Tx or Rx:
932 // Skip to avoid singularity. Simulating a radar tracking its own platform
933 // requires near-field clutter models, not point-target RCS models.
934 if (targ != nullptr &&
935 (targ->getPlatform() == trans->getPlatform() || targ->getPlatform() == recv->getPlatform()))
936 {
937 LOG(Level::TRACE,
938 "Skipping reflected path calculation for Target {} co-located with Transmitter {} or Receiver {}",
939 targ->getName(), trans->getName(), recv->getName());
940 return nullptr;
941 }
942
943 const auto start_time_chrono = std::chrono::duration<RealType>(startTime);
944 const auto end_time_chrono = start_time_chrono + std::chrono::duration<RealType>(signal->getLength());
945 const auto sample_time_chrono = std::chrono::duration<RealType>(1.0 / params::simSamplingRate());
946 const int point_count = static_cast<int>(std::ceil(signal->getLength() / sample_time_chrono.count()));
947
948 if ((targ != nullptr) && point_count == 0)
949 {
950 LOG(Level::FATAL, "No time points are available for execution!");
951 throw std::runtime_error("No time points are available for execution!");
952 }
953
954 auto response = std::make_unique<serial::Response>(signal, trans);
955
956 try
957 {
958 for (int i = 0; i <= point_count; ++i)
959 {
960 const auto current_time =
962
963 ReResults results{};
964 if (targ != nullptr)
965 {
967 }
968 else
969 {
971 }
972
973 interp::InterpPoint const point{.power = results.power,
974 .time = current_time.count() + results.delay,
975 .delay = results.delay,
976 .phase = results.phase};
977 response->addInterpPoint(point);
978 }
979 }
980 catch (const RangeError&)
981 {
982 LOG(Level::INFO, "Receiver or Transmitter too close for accurate simulation");
983 throw; // Re-throw to be caught by the runner
984 }
985
986 return response;
987 }
#define LOG(level,...)
Definition logging.h:19
RealType simSamplingRate() noexcept
Get the simulation sampling rate.
Definition parameters.h:115
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).
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).
Stores data for an interpolation point.

References LOG, max, params::simSamplingRate(), solveRe(), and solveReDirect().

Referenced by core::SimulationEngine::handleTxPulsedStart().

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

◆ calculateStreamingDirectPathContribution()

ComplexType simulation::calculateStreamingDirectPathContribution ( const core::ActiveStreamingSource source,
const radar::Receiver recv,
RealType  timeK,
const CwPhaseNoiseLookup phase_noise_lookup = nullptr,
core::FmcwChirpBoundaryTracker chirp_tracker = nullptr,
StreamingTimingPhaseMode  timing_phase_mode = StreamingTimingPhaseMode::ReceiverRelative 
)

Calculates a direct-path contribution from a cached streaming source.

Parameters
sourceCached active streaming source to evaluate.
recvReceiver observing the source.
timeKCurrent receiver time in seconds.
phase_noise_lookupOptional lookup for timing phase noise samples.
chirp_trackerOptional caller-owned FMCW boundary tracker for this path.
timing_phase_modeSelects how timing phase noise is applied.
Returns
The complex I/Q sample contribution for this path.

Definition at line 748 of file channel_model.cpp.

753 {
754 const auto* const trans = source.transmitter;
755 if (trans == nullptr)
756 {
757 return {0.0, 0.0};
758 }
759 // Check for co-location to prevent singularities.
760 // If they share the same platform, we assume they are isolated (no leakage) or explicit
761 // monostatic handling is required (which is not modeled via the far-field path).
762 if (trans->getPlatform() == recv->getPlatform())
763 {
764 return {0.0, 0.0};
765 }
766
767 const auto p_tx = trans->getPlatform()->getPosition(timeK);
768 const auto p_rx = recv->getPlatform()->getPosition(timeK);
769
770 LinkGeometry link;
771 try
772 {
774 }
775 catch (const RangeError&)
776 {
777 return {0.0, 0.0};
778 }
779
780 const RealType tau = link.dist / params::c();
781 StreamingWaveformEvaluation eval;
783 {
784 return {0.0, 0.0};
785 }
786 const RealType lambda = params::c() / eval.rf_frequency;
787
788 // Tx Gain: Direction Tx -> Rx
790 // Rx Gain: Direction Rx -> Tx (-u_vec)
792
793 const bool no_loss = recv->checkFlag(Receiver::RecvFlag::FLAG_NOPROPLOSS);
795
796 // Include Signal Power
797 const RealType amplitude = source.amplitude * std::sqrt(scaling_factor);
798
799 // Carrier Phase
800 ComplexType contribution = amplitude * eval.envelope * std::polar(1.0, eval.phase);
801
802 // Non-coherent Local Oscillator Effects
804 computeTimingPhase(trans, recv, timeK, timeK - tau, phase_noise_lookup, timing_phase_mode);
805 contribution *= std::polar(1.0, non_coherent_phase);
806
807 return contribution;
808 }
RealType lambda
bool no_loss
double RealType
Type for real numbers.
Definition config.h:27
std::complex< RealType > ComplexType
Type for complex numbers.
Definition config.h:35
RealType c() noexcept
Get the speed of light.
Definition parameters.h:91
RealType amplitude
Cached emitted signal amplitude.
const radar::Transmitter * transmitter
Transmitter active during this segment.

References core::ActiveStreamingSource::amplitude, params::c(), lambda, max, no_loss, and core::ActiveStreamingSource::transmitter.

Referenced by processing::pipeline::applyStreamingInterference(), and calculateDirectPathContribution().

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

◆ calculateStreamingReferencePhase()

bool simulation::calculateStreamingReferencePhase ( const core::ActiveStreamingSource source,
RealType  timeK,
core::FmcwChirpBoundaryTracker chirp_tracker,
RealType phase_out 
)

Evaluates a receive-time streaming waveform phase for receiver LO/dechirp references.

Parameters
sourceCached active streaming source to evaluate.
timeKReceiver time in seconds.
chirp_trackerOptional caller-owned FMCW boundary tracker for this source.
phase_outReceives the waveform phase in radians when evaluation succeeds.
Returns
True when the source is active and a phase was produced.

Definition at line 810 of file channel_model.cpp.

812 {
813 StreamingWaveformEvaluation eval;
815 {
816 return false;
817 }
818 phase_out = eval.phase;
819 if (std::abs(eval.envelope) > 0.0)
820 {
821 phase_out += std::arg(eval.envelope);
822 }
823 return true;
824 }

References max.

◆ calculateStreamingReferenceSample()

bool simulation::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.

Definition at line 826 of file channel_model.cpp.

828 {
829 StreamingWaveformEvaluation eval;
831 {
832 return false;
833 }
834 sample_out = eval.envelope * std::polar(1.0, eval.phase);
835 return true;
836 }

References max.

◆ calculateStreamingReflectedPathContribution()

ComplexType simulation::calculateStreamingReflectedPathContribution ( const core::ActiveStreamingSource source,
const radar::Receiver recv,
const radar::Target targ,
RealType  timeK,
const CwPhaseNoiseLookup phase_noise_lookup = nullptr,
core::FmcwChirpBoundaryTracker chirp_tracker = nullptr,
StreamingTimingPhaseMode  timing_phase_mode = StreamingTimingPhaseMode::ReceiverRelative 
)

Calculates a reflected-path contribution from a cached streaming source.

Parameters
sourceCached active streaming source to evaluate.
recvReceiver observing the reflected signal.
targReflecting target.
timeKCurrent receiver time in seconds.
phase_noise_lookupOptional lookup for timing phase noise samples.
chirp_trackerOptional caller-owned FMCW boundary tracker for this path.
timing_phase_modeSelects how timing phase noise is applied.
Returns
The complex I/Q sample contribution for this reflected path.

Definition at line 846 of file channel_model.cpp.

852 {
853 const auto* const trans = source.transmitter;
854 if (trans == nullptr)
855 {
856 return {0.0, 0.0};
857 }
858 // Check for co-location involving the target.
859 // We do not model a platform tracking itself (R=0) or illuminating itself (R=0).
860 if (trans->getPlatform() == targ->getPlatform() || recv->getPlatform() == targ->getPlatform())
861 {
862 return {0.0, 0.0};
863 }
864
865 const auto p_tx = trans->getPlatform()->getPosition(timeK);
866 const auto p_rx = recv->getPlatform()->getPosition(timeK);
867 const auto p_tgt = targ->getPlatform()->getPosition(timeK);
868
869 LinkGeometry link_tx_tgt;
870 LinkGeometry link_tgt_rx;
871
872 try
873 {
876 }
877 catch (const RangeError&)
878 {
879 return {0.0, 0.0};
880 }
881
882 const RealType tau = (link_tx_tgt.dist + link_tgt_rx.dist) / params::c();
883 StreamingWaveformEvaluation eval;
885 {
886 return {0.0, 0.0};
887 }
888 const RealType lambda = params::c() / eval.rf_frequency;
889
890 // RCS Lookups: In (Tx->Tgt), Out (Rx->Tgt = - (Tgt->Rx))
893 const RealType rcs = targ->getRcs(in_angle, out_angle, timeK);
894
895 // Tx Gain: Direction Tx -> Tgt
897 // Rx Gain: Direction Rx -> Tgt (- (Tgt->Rx)). Time: timeK + tau.
899
900 const bool no_loss = recv->checkFlag(Receiver::RecvFlag::FLAG_NOPROPLOSS);
903
904 // Include Signal Power
905 const RealType amplitude = source.amplitude * std::sqrt(scaling_factor);
906
907 ComplexType contribution = amplitude * eval.envelope * std::polar(1.0, eval.phase);
908
909 // Non-coherent Local Oscillator Effects
911 computeTimingPhase(trans, recv, timeK, timeK - tau, phase_noise_lookup, timing_phase_mode);
912 contribution *= std::polar(1.0, non_coherent_phase);
913
914 return contribution;
915 }
A class representing a vector in spherical coordinates.

References core::ActiveStreamingSource::amplitude, params::c(), lambda, max, no_loss, and core::ActiveStreamingSource::transmitter.

Referenced by processing::pipeline::applyStreamingInterference(), and calculateReflectedPathContribution().

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

◆ solveRe()

void simulation::solveRe ( const radar::Transmitter trans,
const radar::Receiver recv,
const radar::Target targ,
const std::chrono::duration< RealType > &  time,
const fers_signal::RadarSignal wave,
ReResults results 
)

Solves the bistatic radar equation for a reflected path (Tx -> Tgt -> Rx).

This function calculates the signal properties (power, delay, phase) for a signal traveling from a transmitter, reflecting off a target, and arriving at a receiver. It accounts for antenna gains, target RCS, and propagation loss.

Parameters
transPointer to the transmitter.
recvPointer to the receiver.
targPointer to the target.
timeThe time at which the pulse is transmitted.
wavePointer to the transmitted radar signal.
resultsOutput struct to store the calculation results.
Exceptions
RangeErrorIf the target is too close to the transmitter or receiver.

Definition at line 651 of file channel_model.cpp.

653 {
654 // Note: RangeError log messages are handled by the original catch block in calculateResponse
655 // or explicitly here if strict adherence to original logging is required.
656 // Using the helper logic which throws RangeError on epsilon check.
657
658 const RealType t_val = time.count();
659 const auto p_tx = trans->getPosition(t_val);
660 const auto p_rx = recv->getPosition(t_val);
661 const auto p_tgt = targ->getPosition(t_val);
662
663 // Link 1: Tx -> Target
664 LinkGeometry link_tx_tgt;
665 // Link 2: Target -> Rx (Note: Vector for calculation is Tgt->Rx)
666 LinkGeometry link_tgt_rx;
667
668 try
669 {
671 link_tgt_rx = computeLink(p_tgt, p_rx); // Vector Tgt -> Rx
672 }
673 catch (const RangeError&)
674 {
675 LOG(Level::INFO, "Transmitter or Receiver too close to Target for accurate simulation");
676 throw;
677 }
678
679 results.delay = (link_tx_tgt.dist + link_tgt_rx.dist) / params::c();
680
681 // Calculate RCS
682 // Note: getRcs expects (InAngle, OutAngle).
683 // InAngle: Tx -> Tgt (link_tx_tgt.u_vec)
684 // OutAngle: Rx -> Tgt (Opposite of Tgt->Rx, so -link_tgt_rx.u_vec)
685 // This matches existing logic.
688 const auto rcs = targ->getRcs(in_angle, out_angle, t_val);
689
690 const auto wavelength = params::c() / wave->getCarrier();
691
692 // Tx Gain: Direction Tx -> Tgt
694 // Rx Gain: Direction Rx -> Tgt (Opposite of Tgt->Rx).
695 // Time is time + delay.
696 const auto rx_gain = computeAntennaGain(recv, -link_tgt_rx.u_vec, results.delay + t_val, wavelength);
697
698 const bool no_loss = recv->checkFlag(Receiver::RecvFlag::FLAG_NOPROPLOSS);
699 results.power =
701
702 results.phase = -results.delay * 2 * PI * wave->getCarrier();
703 }
constexpr RealType PI
Mathematical constant π (pi).
Definition config.h:43

References params::c(), LOG, max, no_loss, and PI.

Referenced by calculateResponse().

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

◆ solveReDirect()

void simulation::solveReDirect ( const radar::Transmitter trans,
const radar::Receiver recv,
const std::chrono::duration< RealType > &  time,
const fers_signal::RadarSignal wave,
ReResults results 
)

Solves the radar equation for a direct path (Tx -> Rx).

This function calculates the signal properties for a direct line-of-sight signal traveling from a transmitter to a receiver.

Parameters
transPointer to the transmitter.
recvPointer to the receiver.
timeThe time at which the pulse is transmitted.
wavePointer to the transmitted radar signal.
resultsOutput struct to store the calculation results.
Exceptions
RangeErrorIf the transmitter and receiver are too close.

Definition at line 705 of file channel_model.cpp.

707 {
708 const RealType t_val = time.count();
709 const auto p_tx = trans->getPosition(t_val);
710 const auto p_rx = recv->getPosition(t_val);
711
712 LinkGeometry link;
713 try
714 {
715 link = computeLink(p_tx, p_rx); // Vector Tx -> Rx
716 }
717 catch (const RangeError&)
718 {
719 LOG(Level::INFO, "Transmitter or Receiver too close for accurate simulation");
720 throw;
721 }
722
723 results.delay = link.dist / params::c();
724 const RealType wavelength = params::c() / wave->getCarrier();
725
726 // Discrepancy Fix: Original code used (Rx - Tx) for Receiver Gain but (Tx - Rx) logic for Transmitter gain
727 // was ambiguous/incorrect (using `tpos - rpos` which is Rx->Tx).
728 // Per `calculateDirectPathContribution` preference:
729 // Tx Gain uses Vector Tx -> Rx.
730 // Rx Gain uses Vector Rx -> Tx.
731
732 const auto tx_gain = computeAntennaGain(trans, link.u_vec, t_val, wavelength);
733 const auto rx_gain = computeAntennaGain(recv, -link.u_vec, t_val + results.delay, wavelength);
734
735 const bool no_loss = recv->checkFlag(Receiver::RecvFlag::FLAG_NOPROPLOSS);
737
738 results.phase = -results.delay * 2 * PI * wave->getCarrier();
739 }

References params::c(), LOG, max, no_loss, and PI.

Referenced by calculateResponse().

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