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.
 
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 275 of file channel_model.h.

276 {
277 Strong, ///< SNR > 0 dB
278 Weak ///< SNR < 0 dB (Geometric line of sight, but below noise floor)
279 };
@ 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 263 of file channel_model.h.

264 {
265 Monostatic, ///< Combined Tx/Rx path
266 BistaticTxTgt, ///< Illuminator path
267 BistaticTgtRx, ///< Scattered path
268 DirectTxRx ///< Interference path
269 };
@ 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 702 of file channel_model.cpp.

704 {
706 phase_noise_lookup);
707 }
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 1122 of file channel_model.cpp.

1123 {
1124 std::vector<PreviewLink> links;
1125
1126 for (const auto& tx : world.getTransmitters())
1127 {
1128 if (!isComponentActive(tx->getSchedule(), time))
1129 {
1130 continue;
1131 }
1132
1133 const auto tx_ctx = makePreviewTransmitterContext(*tx, time);
1134 addIlluminatorLinks(links, tx_ctx, world, time);
1135
1136 for (const auto& rx : world.getReceivers())
1137 {
1138 if (!isComponentActive(rx->getSchedule(), time))
1139 {
1140 continue;
1141 }
1142 const auto rx_ctx = makePreviewReceiverContext(*rx, time);
1143 addReceiverLinks(links, tx_ctx, rx_ctx, world, time);
1144 }
1145 }
1146 return links;
1147 }

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 781 of file channel_model.cpp.

784 {
786 phase_noise_lookup);
787 }
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 864 of file channel_model.cpp.

867 {
868 // If calculating direct path (no target) and components are co-located:
869 // 1. If explicitly attached (monostatic), skip (internal leakage handled elsewhere).
870 // 2. If independent but on the same platform, distance is 0. Far-field logic (1/R^2)
871 // diverges. We skip calculation to avoid RangeError crashes, assuming
872 // no direct coupling/interference for co-located far-field antennas.
873 if (targ == nullptr && (trans->getAttached() == recv || trans->getPlatform() == recv->getPlatform()))
874 {
875 return nullptr;
876 }
877
878 // If calculating reflected path and target is co-located with either Tx or Rx:
879 // Skip to avoid singularity. Simulating a radar tracking its own platform
880 // requires near-field clutter models, not point-target RCS models.
881 if (targ != nullptr &&
882 (targ->getPlatform() == trans->getPlatform() || targ->getPlatform() == recv->getPlatform()))
883 {
884 LOG(Level::TRACE,
885 "Skipping reflected path calculation for Target {} co-located with Transmitter {} or Receiver {}",
886 targ->getName(), trans->getName(), recv->getName());
887 return nullptr;
888 }
889
890 const auto start_time_chrono = std::chrono::duration<RealType>(startTime);
891 const auto end_time_chrono = start_time_chrono + std::chrono::duration<RealType>(signal->getLength());
892 const auto sample_time_chrono = std::chrono::duration<RealType>(1.0 / params::simSamplingRate());
893 const int point_count = static_cast<int>(std::ceil(signal->getLength() / sample_time_chrono.count()));
894
895 if ((targ != nullptr) && point_count == 0)
896 {
897 LOG(Level::FATAL, "No time points are available for execution!");
898 throw std::runtime_error("No time points are available for execution!");
899 }
900
901 auto response = std::make_unique<serial::Response>(signal, trans);
902
903 try
904 {
905 for (int i = 0; i <= point_count; ++i)
906 {
907 const auto current_time =
909
910 ReResults results{};
911 if (targ != nullptr)
912 {
914 }
915 else
916 {
918 }
919
920 interp::InterpPoint const point{.power = results.power,
921 .time = current_time.count() + results.delay,
922 .delay = results.delay,
923 .phase = results.phase};
924 response->addInterpPoint(point);
925 }
926 }
927 catch (const RangeError&)
928 {
929 LOG(Level::INFO, "Receiver or Transmitter too close for accurate simulation");
930 throw; // Re-throw to be caught by the runner
931 }
932
933 return response;
934 }
#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 709 of file channel_model.cpp.

714 {
715 const auto* const trans = source.transmitter;
716 if (trans == nullptr)
717 {
718 return {0.0, 0.0};
719 }
720 // Check for co-location to prevent singularities.
721 // If they share the same platform, we assume they are isolated (no leakage) or explicit
722 // monostatic handling is required (which is not modeled via the far-field path).
723 if (trans->getPlatform() == recv->getPlatform())
724 {
725 return {0.0, 0.0};
726 }
727
728 const auto p_tx = trans->getPlatform()->getPosition(timeK);
729 const auto p_rx = recv->getPlatform()->getPosition(timeK);
730
731 LinkGeometry link;
732 try
733 {
735 }
736 catch (const RangeError&)
737 {
738 return {0.0, 0.0};
739 }
740
741 const RealType tau = link.dist / params::c();
742 if (source.carrier_freq <= 0.0)
743 {
744 return {0.0, 0.0};
745 }
746 const RealType lambda = params::c() / source.carrier_freq;
747
748 // Tx Gain: Direction Tx -> Rx
750 // Rx Gain: Direction Rx -> Tx (-u_vec)
752
753 const bool no_loss = recv->checkFlag(Receiver::RecvFlag::FLAG_NOPROPLOSS);
755
756 // Include Signal Power
757 const RealType amplitude = source.amplitude * std::sqrt(scaling_factor);
758
759 // Carrier Phase
760 RealType phase = 0.0;
761 if (!computeStreamingPhase(source, timeK, tau, chirp_tracker, phase))
762 {
763 return {0.0, 0.0};
764 }
765 ComplexType contribution = std::polar(amplitude, phase);
766
767 // Non-coherent Local Oscillator Effects
769 computeTimingPhase(trans, recv, timeK, timeK - tau, phase_noise_lookup, timing_phase_mode);
770 contribution *= std::polar(1.0, non_coherent_phase);
771
772 return contribution;
773 }
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.
RealType carrier_freq
Cached carrier frequency in hertz.
const radar::Transmitter * transmitter
Transmitter active during this segment.

References core::ActiveStreamingSource::amplitude, params::c(), core::ActiveStreamingSource::carrier_freq, 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 775 of file channel_model.cpp.

777 {
778 return computeStreamingPhase(source, timeK, 0.0, chirp_tracker, phase_out);
779 }

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 789 of file channel_model.cpp.

795 {
796 const auto* const trans = source.transmitter;
797 if (trans == nullptr)
798 {
799 return {0.0, 0.0};
800 }
801 // Check for co-location involving the target.
802 // We do not model a platform tracking itself (R=0) or illuminating itself (R=0).
803 if (trans->getPlatform() == targ->getPlatform() || recv->getPlatform() == targ->getPlatform())
804 {
805 return {0.0, 0.0};
806 }
807
808 const auto p_tx = trans->getPlatform()->getPosition(timeK);
809 const auto p_rx = recv->getPlatform()->getPosition(timeK);
810 const auto p_tgt = targ->getPlatform()->getPosition(timeK);
811
812 LinkGeometry link_tx_tgt;
813 LinkGeometry link_tgt_rx;
814
815 try
816 {
819 }
820 catch (const RangeError&)
821 {
822 return {0.0, 0.0};
823 }
824
825 const RealType tau = (link_tx_tgt.dist + link_tgt_rx.dist) / params::c();
826 if (source.carrier_freq <= 0.0)
827 {
828 return {0.0, 0.0};
829 }
830 const RealType lambda = params::c() / source.carrier_freq;
831
832 // RCS Lookups: In (Tx->Tgt), Out (Rx->Tgt = - (Tgt->Rx))
835 const RealType rcs = targ->getRcs(in_angle, out_angle, timeK);
836
837 // Tx Gain: Direction Tx -> Tgt
839 // Rx Gain: Direction Rx -> Tgt (- (Tgt->Rx)). Time: timeK + tau.
841
842 const bool no_loss = recv->checkFlag(Receiver::RecvFlag::FLAG_NOPROPLOSS);
845
846 // Include Signal Power
847 const RealType amplitude = source.amplitude * std::sqrt(scaling_factor);
848
849 RealType phase = 0.0;
850 if (!computeStreamingPhase(source, timeK, tau, chirp_tracker, phase))
851 {
852 return {0.0, 0.0};
853 }
854 ComplexType contribution = std::polar(amplitude, phase);
855
856 // Non-coherent Local Oscillator Effects
858 computeTimingPhase(trans, recv, timeK, timeK - tau, phase_noise_lookup, timing_phase_mode);
859 contribution *= std::polar(1.0, non_coherent_phase);
860
861 return contribution;
862 }
A class representing a vector in spherical coordinates.

References core::ActiveStreamingSource::amplitude, params::c(), core::ActiveStreamingSource::carrier_freq, 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 612 of file channel_model.cpp.

614 {
615 // Note: RangeError log messages are handled by the original catch block in calculateResponse
616 // or explicitly here if strict adherence to original logging is required.
617 // Using the helper logic which throws RangeError on epsilon check.
618
619 const RealType t_val = time.count();
620 const auto p_tx = trans->getPosition(t_val);
621 const auto p_rx = recv->getPosition(t_val);
622 const auto p_tgt = targ->getPosition(t_val);
623
624 // Link 1: Tx -> Target
625 LinkGeometry link_tx_tgt;
626 // Link 2: Target -> Rx (Note: Vector for calculation is Tgt->Rx)
627 LinkGeometry link_tgt_rx;
628
629 try
630 {
632 link_tgt_rx = computeLink(p_tgt, p_rx); // Vector Tgt -> Rx
633 }
634 catch (const RangeError&)
635 {
636 LOG(Level::INFO, "Transmitter or Receiver too close to Target for accurate simulation");
637 throw;
638 }
639
640 results.delay = (link_tx_tgt.dist + link_tgt_rx.dist) / params::c();
641
642 // Calculate RCS
643 // Note: getRcs expects (InAngle, OutAngle).
644 // InAngle: Tx -> Tgt (link_tx_tgt.u_vec)
645 // OutAngle: Rx -> Tgt (Opposite of Tgt->Rx, so -link_tgt_rx.u_vec)
646 // This matches existing logic.
649 const auto rcs = targ->getRcs(in_angle, out_angle, t_val);
650
651 const auto wavelength = params::c() / wave->getCarrier();
652
653 // Tx Gain: Direction Tx -> Tgt
655 // Rx Gain: Direction Rx -> Tgt (Opposite of Tgt->Rx).
656 // Time is time + delay.
657 const auto rx_gain = computeAntennaGain(recv, -link_tgt_rx.u_vec, results.delay + t_val, wavelength);
658
659 const bool no_loss = recv->checkFlag(Receiver::RecvFlag::FLAG_NOPROPLOSS);
660 results.power =
662
663 results.phase = -results.delay * 2 * PI * wave->getCarrier();
664 }
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 666 of file channel_model.cpp.

668 {
669 const RealType t_val = time.count();
670 const auto p_tx = trans->getPosition(t_val);
671 const auto p_rx = recv->getPosition(t_val);
672
673 LinkGeometry link;
674 try
675 {
676 link = computeLink(p_tx, p_rx); // Vector Tx -> Rx
677 }
678 catch (const RangeError&)
679 {
680 LOG(Level::INFO, "Transmitter or Receiver too close for accurate simulation");
681 throw;
682 }
683
684 results.delay = link.dist / params::c();
685 const RealType wavelength = params::c() / wave->getCarrier();
686
687 // Discrepancy Fix: Original code used (Rx - Tx) for Receiver Gain but (Tx - Rx) logic for Transmitter gain
688 // was ambiguous/incorrect (using `tpos - rpos` which is Rx->Tx).
689 // Per `calculateDirectPathContribution` preference:
690 // Tx Gain uses Vector Tx -> Rx.
691 // Rx Gain uses Vector Rx -> Tx.
692
693 const auto tx_gain = computeAntennaGain(trans, link.u_vec, t_val, wavelength);
694 const auto rx_gain = computeAntennaGain(recv, -link.u_vec, t_val + results.delay, wavelength);
695
696 const bool no_loss = recv->checkFlag(Receiver::RecvFlag::FLAG_NOPROPLOSS);
698
699 results.phase = -results.delay * 2 * PI * wave->getCarrier();
700 }

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: